import * as d3 from "./d3.v5.js";
import { getBlobPath } from '@/utils/downFIleByBlob'
import { getLocalStorage } from "./storage.js";

/**
 * 指定したURLの画像オブジェクト取得（画像サイズ取得用）
 * @param {*} e blobUrl：取得対象画像ファイルURL
 */
function getImageSize(blobUrl) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.onload = () => {
                resolve({ width: img.width, height: img.height });
            };
            img.onerror = reject;
            img.src = blobUrl;
        });
    }

/**
 * ViewBoxの幅（initMarkupLayerの引数保持用）
 */
var g_boxWidth;

/**
 * ViewBoxの高さ（initMarkupLayerの引数保持用）
 */
var g_boxHeight;

var _self = {
        transScale: {
                transX: 0,
                transY: 0,
                scale: 0,
                transYRatio: -100
        },
        markup_groups: {},
        markup_groups_bottom: {},
        ballmarkup_groups: {}
};

_self.zoom = d3
        .zoom() //定义缩放方法
        .duration(750)
        .on("zoom", function () {
                // zoom事件
                _self.circles_group.attr(
                        "transform",
                        d3.zoomTransform(_self.svg.node()) + " scale(1," + g_UpSideDown + ")"
                ); //缩放平移都是在操作g元素  + " rotate(0)"
        });


/**
 * 图纸摆放在窗口的中间，x方向偏移可以是0，y方向必须偏移固定的值，暂时未査出来原因
 * 
 */
var g_globalSvgBoundingBoxRatioX = 0;
var g_globalSvgBoundingBoxRatioY = 0;
var g_globalSvgScaleRatio = 0.9;

/**
 * line stoken type
 */
var LINE_STROKE_DASH_TYPE = [
        "0",
        "2,1",
        "0.5,1.5",
        "2,1,1,1",
        "2,1,1,1,1,1",
];

/**
 * opt state 
 * STATE_NORMAL 普通状态
 * STATE_CHANGING 点击包围盒上的小点，改变形状
 * STATE_MOVING 位置移动
 * STATE_ADDING 增加形状
 */
var OPT_STATE = {
        STATE_NORMAL: 0,
        STATE_CHANGING: 1,
        STATE_MOVING: 2,
        STATE_ADDING: 3,
};

/**
 * 选中Markup
 */
var g_SelectedMarkup = null;

/**
 * 包围盒关键点宽度
 */
var g_editDotWidth = 1; // 包围盒黑点宽度
var g_editDotWidthRatio = 1; // 包围盒黑点默认宽度的倍数
/**
 * 包围盒关键点颜色
 */
var g_editDotStroke = "#000000"; // 包围盒黑点宽度

/**
 * 包围盒关键点填充颜色
 */
var g_editDotFill = "#000000"; // 包围盒黑点宽度

/**
 * 用于移动  标记上一次位置
 */
var g_moveLastPos = {
        x: 0,
        y: 0
};

/**
 * 页面传入选择的图形参数
 */
var g_params = {};

/**
 * 页面传入创建的图形类型id
 */
var g_createShapeTypeId = -1;

/**
 * 页面传入创建的图形类型id
 */
var g_isMarkupStatus = false;

/**
 * 选中markup后的callback
 */
var g_selectedCallBackFun;

/**
 * 打开textinput回调
 */
var g_openTextInputFun;

/**
 * 加载成功后的回调
 */
var g_loadCallback;

/**
 * 提取xml中creator信息后的回调，传递到外围页面
 */
var g_updateMarkupBaseInfoFun;

/**
 * 右键双击
 */
var g_contextMenuDoubleClickFun;

/**
 * 左键双击
 */
var g_leftMouseClickFun;

/**
 * 返回球标数据
 */
var g_onAddMarkupDataFun;

var g_filePath;

/**
 * markup默认线宽
 */
var g_markupLineWidth = 1;
var g_markupTextDefaultWidth = 1;

/**
 * 全局线宽倍数
 */
var g_svgLineWidthRatio = 1.0;

function setSvgLineWidthRatio(e) {
        g_svgLineWidthRatio = e;
}

/**
 * 全局状态
 */
var g_state = OPT_STATE.STATE_NORMAL;

/**
 * 点击操作的包围盒关键点id
 */
var g_dotIndex = -1; // 点击的包围盒点的index  用于确定跟随鼠标移动的动作类型

/**
 * 所有markup対象list
 */
var g_markupList = []; // 所有markup対象

/**
 * markup图形位置偏移，某些xml中含有偏移信息
 */
var g_positionDeviation = {
        x: 0,
        y: 0
};

/**
 * 是否响应下一次右键事件
 */
var g_doRightClick = true;

/**
 * markup层列表
 */
var g_layerList = []; // 所有markup対象

/**
 * markup选中层
 */
var g_layerActiveId = -1;

/**
 * マークアップグループのスケール
 */
var g_markupsScale = 1;

/**
 * マークアップグループのMove座標値(横幅)
 */
var g_markupsOffsetWidth = 0;

/**
 * マークアップグループのMove座標値(縦幅)
 */
var g_markupsOffsetHeight = 0;

/**
 * 原版skmarker中的字体名字，转为字体代码
 */
var g_FontImportCompareList = [{
        importName: "ＭＳ Ｐゴシック",
        value: "ＭＳ Ｐゴシック",
}, {
        importName: "ＭＳ Ｐ明朝",
        value: "ＭＳ Ｐ明朝",
}, {
        importName: "MS UI Gothic",
        value: "MS UI Gothic",
}, {
        importName: "ＭＳ ゴシック",
        value: "ＭＳ ゴシック",
}, {
        importName: "ＭＳ 明朝",
        value: "ＭＳ 明朝",
}, {
        importName: "Yu Gothic UI Regular",
        value: "Yu Gothic UI",
}, {
        importName: "メイリオ",
        value: "メイリオ",
}, {
        importName: "游ゴシック Regular",
        value: "游ゴシック",
}];

var g_ballMarkerSelectColor = "#ff0000";

/**
 * 是否markup状态  外部传入
 * @param {*} e 
 */
function setIsMarkupStatus(e) {
        g_isMarkupStatus = e;
}

/**
 * 包围盒上的控制cube 基础宽度因子  
 * @param {*} e 
 */
function setEditDotWidthRatio(e) {
        g_editDotWidthRatio = e;
}

/**
 * 允许鼠标点击选中markup
 */
var g_canClickSelectMarkup = true;
var g_clickSelectExceptTypeList = [];

function setCanClickSelectMarkup(e, exceptTypeList = []) {
        g_canClickSelectMarkup = e;
        g_clickSelectExceptTypeList = exceptTypeList;
}

/**
 * 允许鼠标位移、修改选中markup
 */
var g_canEditSelectMarkup = true;

function setCanEditSelectMarkup(e) {
        g_canEditSelectMarkup = e;
}

/**
 * 
 * @param {*} x 
 * @param {*} y 
 * @param {*} scale 
 */
var isMouseMove = false;

/**
 * 
 * @param {*} x 图纸窗口x偏移
 * @param {*} y 图纸窗口y偏移
 * @param {*} scale 图纸窗口scale偏移 
 */
function setSvgBoundingBoxRatio(x, y, scale = 0.9) {
        g_globalSvgBoundingBoxRatioX = x;
        g_globalSvgBoundingBoxRatioY = y;
        g_globalSvgScaleRatio = scale
}

var g_canFitPositionAndScale = true;
/**
 * 
 * @param {*} x 图纸窗口x偏移
 * @param {*} y 图纸窗口y偏移
 * @param {*} scale 图纸窗口scale偏移 
 */
function setCanFitPositionAndScale(e) {
        g_canFitPositionAndScale = e;
}


var zoomOnce = d3
        .zoom() //定义缩放方法
        // .scaleExtent()
        .duration(750)
        .on("zoom", function () {
                _self.circles_group.attr(
                        "transform",
                        d3.zoomTransform(_self.svg.node()) + " scale(1," + g_UpSideDown + ")"
                ); //缩放平移都是在操作g元素  + " rotate(0)"
        });

var isMarkupConfirmed = false;

var g_UpSideDown = -1;

/**
 * 加载svg图纸到画布中
 * @param {*} filePath svg地址
 * @param {*} divId 标签
 * @param {*} mouseCallBack 鼠标移动的回调
 */
async function AddSvg(filePath, divId, mouseCallBack, shapesLayoutChangeCallBack, flg = false, imgWidth = 0, imgHeight = 0, upSideDown = -1) {
        g_filePath = filePath;
        isMouseMove = flg;
        g_UpSideDown = upSideDown;
        var f = document.getElementById(divId);
        var childs = f.childNodes;
        for (var i = 0; i < childs.length; i++) {
                f.removeChild(childs[i]);
        }
        g_markupList = [];

        var tar = document.getElementById(divId);

        tar.innerHTML = "";
        d3.select(tar)
                .append("style");

        //屏蔽右键
        // tar.oncontextmenu = function () {
        //   // event.returnValue = false;
        // };
        let token = getLocalStorage('token')
        d3.svg(filePath,
                {
                        method: 'GET', // 或者 'POST', 'PUT' 等  
                        headers: {
                                // 设置其他请求头，如 'Content-Type': 'application/json'（対于POST请求）  
                                'Authorization': `Bearer ${token}`, // 如果需要的话  
                                // 注意：Fetch API不会自动处理cookies，你需要手动处理  
                                // 但浏览器通常会在同源请求中自动发送cookies  
                                // 如果你需要在跨域请求中发送cookies，你需要在服务器端设置CORS策略来允许credentials  
                                'Credentials': 'include' // 注意：这不是一个有效的Fetch API header，而是CORS策略的一部分    
                        }
                }
        ).then(function (data) {
                try {
                        var test = data.getElementsByTagName("svg"); //取出画布中的内容
                        _self.svg = d3
                                .select("#" + tar.id)
                                .append("svg")
                                .attr("id", "svg" + tar.id); //创建画布


                        var parbox = tar.getBoundingClientRect();
                        var parentOffsetX = parbox.x;
                        var parentOffsetY = parbox.y;

                        if (test["0"].children.length > 0) {
                                let children = test["0"].children;
                                for (var cnt = 0; cnt < children.length; cnt++) {
                                        if (children[cnt].tagName == "style") {
                                                let styleText = children[cnt].innerHTML;
                                                styleText = styleText.replaceAll(';', ' !important;');
                                                test["0"].children[cnt].innerHTML = styleText;
                                        }
                                }
                        }

                        var docdata = test["0"].innerHTML;

                        _self.circles_group = _self.svg.append("g").attr("id", "g" + tar.id); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                        _self.circles_group.html(docdata);

                        var padding = 0; //边距
                        var clientHeight = tar.offsetHeight - padding; //  window.innerHeight - padding;
                        var clientWidth = tar.offsetWidth - padding; //document.body.offsetWidth - padding; //window.innerWidth;

                        _self.svg
                                .attr("preserveAspectRatio", "xMinYMin meet")
                                .attr("width", clientWidth)
                                .attr("hieght", clientHeight)
                                .attr("rotate", 180)
                                .attr("viewBox", "0 0 " + clientWidth + " " + clientHeight + ""); //这里是容器的宽高

                        console.log("=============== init ================")

                        var boundbox = _self.circles_group.node().getBoundingClientRect();

                        var svgheight = boundbox.height;
                        var svgwidth = boundbox.width;
                        console.log("svgwidth :" + svgwidth)
                        console.log("svgheight :" + svgheight)

                        var ScalingRatio = g_globalSvgScaleRatio * Math.min(
                                clientHeight / svgheight,
                                clientWidth / svgwidth
                        );

                        boundbox.x = boundbox.x + g_globalSvgBoundingBoxRatioX;
                        boundbox.y = boundbox.y - parentOffsetY * 1;
                        boundbox.y = boundbox.y - g_globalSvgBoundingBoxRatioY / ScalingRatio;

                        g_editDotWidth = Math.min(svgwidth / 500, svgheight / 500) * g_editDotWidthRatio;
                        g_markupLineWidth = Math.min(svgwidth, svgheight) / 1500 * g_svgLineWidthRatio;
                        g_markupTextDefaultWidth = 5 * Math.min(svgwidth, svgheight) / 1500;

                        var scalex = (0 - boundbox.x + parentOffsetX) * ScalingRatio;
                        scalex += (clientWidth - boundbox.width * ScalingRatio) / 2;
                        var scaley = (0 + boundbox.y) * ScalingRatio;
                        scaley += clientHeight - (clientHeight - boundbox.height * ScalingRatio) / 2;

                        _self.transScale.transX = scalex;
                        _self.transScale.transY = scaley;
                        _self.transScale.scale = ScalingRatio;

                        _self.svg
                                .call(zoomOnce)
                                .call(
                                        zoomOnce.transform,
                                        d3.zoomIdentity.translate(scalex, upSideDown === 1 ? 0 : scaley).scale(ScalingRatio)
                                );
                        d3.SetInitScale(_self.transScale.scale);

                        //   背景框  用于鼠标位置检测
                        _self.circles_group.on("mousemove", function () {
                                // 添加交互内容
                                var x = (d3.mouse(this)[0] - (g_markupsOffsetWidth)) / g_markupsScale;
                                var y = (d3.mouse(this)[1] - (g_markupsOffsetHeight !== 0 ? -g_markupsOffsetHeight : 0)) / g_markupsScale;

                                if (mouseCallBack != null) {
                                        // 图片类的y向下为正
                                        if (g_filePath.indexOf('/static/img/method-draw-image') >= 0) {
                                                mouseCallBack(x, y <= 0 ? Math.abs(y) : -y);
                                        } else {
                                                mouseCallBack(x, y);
                                        }
                                        // mouseCallBack(x, y);
                                }
                                _self.mousePosX = x;
                                _self.mousePosY = y;

                                if (g_SelectedMarkup) {
                                        g_SelectedMarkup.onBoundBoxDotMouseMove(g_dotIndex);
                                        g_SelectedMarkup.onBoundBoxShapeMouseMove(g_dotIndex);
                                }

                                if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup != null && !isMarkupConfirmed) {
                                        g_SelectedMarkup.updateLastPosition({
                                                x: x,
                                                y: y
                                        }, false);
                                }
                        });

                        // 鼠标右键
                        _self.circles_group.on("contextmenu", function () {
                                event.returnValue = false;
                                //右键单击
                                var x = (d3.mouse(this)[0] - (g_markupsOffsetWidth)) / g_markupsScale;
                                var y = (d3.mouse(this)[1] - (g_markupsOffsetHeight !== 0 ? -g_markupsOffsetHeight : 0)) / g_markupsScale;
                                var but = d3.event.button;
                                console.log("but = " + but)

                                if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup != null && !isMarkupConfirmed) {
                                        g_SelectedMarkup.updateLastPosition({
                                                x: x,
                                                y: y
                                        }, true);

                                        g_SelectedMarkup.setSelected(true);

                                        if (g_SelectedMarkup.typeId == 11) {
                                                g_openTextInputFun(g_SelectedMarkup.originData.text);

                                        } else {
                                                changeGlobalState(3, g_createShapeTypeId);
                                        }

                                        event.stopPropagation(); //阻止事件冒泡
                                        event.preventDefault(); //阻止默认行为
                                } else if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup != null && isMarkupConfirmed) {
                                        changeGlobalState(0, g_createShapeTypeId, true);
                                        shapesLayoutChangeCallBack();
                                } else if (g_doRightClick) {
                                        if (!g_isMarkupStatus) {
                                                if (g_canFitPositionAndScale)
                                                        ResetSvgView();
                                        } else {
                                                if (g_createShapeTypeId != 0 && g_createShapeTypeId != -1) {
                                                        if (g_contextMenuDoubleClickFun)
                                                                g_contextMenuDoubleClickFun();
                                                } else if ((g_createShapeTypeId == 0 || g_createShapeTypeId == -1) && g_SelectedMarkup != null) {
                                                        clearSelectedState();
                                                } else if ((g_createShapeTypeId == 0 || g_createShapeTypeId == -1) && g_SelectedMarkup == null) {
                                                        // ResetSvgView();
                                                }

                                        }
                                        isMarkupConfirmed = false;
                                } else {
                                        isMarkupConfirmed = false;
                                }

                                if (!g_doRightClick)
                                        g_doRightClick = true;
                        });

                        _self.circles_group.on("dblclick", function () {
                                console.log("dblclick")
                        });

                        _self.circles_group.on("mousedown", function () {
                                var but = d3.event.button;
                                console.log("but = " + but)

                                if (but != 0)
                                        return;
                                if (g_leftMouseClickFun)
                                        g_leftMouseClickFun();
                        });

                        // 鼠标左键
                        _self.circles_group.on("mouseup", function () {
                                // 添加交互内容
                                var x = (d3.mouse(this)[0] - (g_markupsOffsetWidth)) / g_markupsScale;
                                var y = (d3.mouse(this)[1] - (g_markupsOffsetHeight !== 0 ? -g_markupsOffsetHeight : 0)) / g_markupsScale;
                                console.log("mouseup x = " + x + " y = " + y)

                                var but = d3.event.button;
                                console.log("but = " + but)

                                if (but != 0)
                                        return;

                                var _changeToAdd = false;
                                if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup == null) {
                                        g_SelectedMarkup = addMarkUpByParams(g_createShapeTypeId, g_params, {
                                                x: x,
                                                y: y
                                        });
                                } else if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup != null && isMarkupConfirmed) {
                                        clearSelectedState();
                                        g_SelectedMarkup = addMarkUpByParams(g_createShapeTypeId, g_params, {
                                                x: x,
                                                y: y
                                        });
                                } else if (g_state == OPT_STATE.STATE_ADDING && g_SelectedMarkup != null && !isMarkupConfirmed) {
                                        _changeToAdd = addMarkUpPosition(g_createShapeTypeId, g_params, {
                                                x: x,
                                                y: y
                                        });
                                } else if (g_state == OPT_STATE.STATE_CHANGING) {
                                        // var dataindex = d3.select(this).attr("dataIndex");
                                        g_SelectedMarkup.onBoundBoxDotMouseUp(g_dotIndex);
                                        g_dotIndex = -1;
                                        event.stopPropagation(); //阻止事件冒泡
                                        event.preventDefault(); //阻止默认行为
                                }

                                isMarkupConfirmed = false;

                                if (_changeToAdd) {
                                        g_SelectedMarkup.updateLastPosition({
                                                x: x,
                                                y: y
                                        }, true);
                                        changeGlobalState(3, g_createShapeTypeId);
                                        g_SelectedMarkup.setSelected(true);
                                        event.stopPropagation(); //阻止事件冒泡
                                        event.preventDefault(); //阻止默认行为
                                }

                        });

                        changeWholeLineWidth("g", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("circle", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("rect", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("ellipse", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("path", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("line", g_markupLineWidth * 0.9);
                        changeWholeLineWidth("polyline", g_markupLineWidth * 0.5);

                        var boxX = test[0].viewBox.baseVal.x;
                        var boxY = test[0].viewBox.baseVal.y;
                        var boxWidth = test[0].viewBox.baseVal.width;
                        var boxHeight = test[0].viewBox.baseVal.height;
                        initMarkupLayer(boxX, boxY, boxWidth, boxHeight, imgWidth, imgHeight);

                        // markup标记偏移量归零
                        g_positionDeviation.x = 0;
                        g_positionDeviation.y = 0;

                        if (g_loadCallback)
                                g_loadCallback();
                } catch (e) {
                        if (g_loadCallback)
                                g_loadCallback(e);
                }
        });
}

function removeSvg() {
        if (_self.circles_group)
                _self.circles_group.html("");
}

/**
 * 改变指定类型图形的线宽，虚线间隔
 * @param {*} inTag 修改的图形类型
 */
function changeWholeLineWidth(inTag, inNum) {
        var ellipse = _self.circles_group.selectAll(inTag);
        ellipse.attr("stroke-width", function () {
                return inNum;
        });

        ellipse.attr("stroke-dasharray", function () {
                var dash = this.getAttribute("stroke-dasharray")
                if (dash != null) {
                        var textDashs = dash.split(",");
                        for (var i = 0; i < textDashs.length; i++) {
                                if (Number(textDashs[i]) < g_markupLineWidth * 1.5) {
                                        textDashs[i] = g_markupLineWidth * 1.5;
                                }
                        }
                        var newDashStr = textDashs.join(",");
                        return newDashStr;
                }
        });
}

function ResetSvgView() {
        _self.svg.call(
                _self.zoom.transform,
                d3.zoomIdentity
                        .translate(_self.transScale.transX, g_UpSideDown === 1 ? 0 : _self.transScale.transY)
                        .scale(_self.transScale.scale)
        );
        d3.SetInitScale(_self.transScale.scale);
}

/**
 * 设置鼠标操作类型  1 缩放  2 移动
 * @param {*} index mode  index
 */
function SetSvgMouseMode(index) {
        d3.SetMouseMode(index);
}

function GetMousePositonOnSvgX() {
        return _self.mousePosX;
}

function GetMousePositonOnSvgY() {
        return _self.mousePosY;
}

/**
 * 创建标记区域层 图纸viewbox参数 x\y\width\height
 * @param {*} boxX 
 * @param {*} boxY 
 * @param {*} boxWidth 
 * @param {*} boxHeight 
 */
function initMarkupLayer(boxX, boxY, boxWidth, boxHeight, imgWidth, imgHeight) {

        _self.markup_groups_bottom = _self.circles_group.insert("g", "clipId0").attr("id", "g-markups-bottom"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
        _self.markup_groups_bottom.each(function () {
                this.parentNode.insertBefore(this, this.parentNode.firstChild);
        });


        var backgroundBox = _self.circles_group
                .insert("rect", "g-markups-bottom")
                .attr("id", "backRect");
        backgroundBox.attr("style", "fill:rgba(0,0,255,0)");
        backgroundBox.attr("fill", "rgba(0,0,255,0)");

        backgroundBox.attr("x", boxX - boxWidth);
        backgroundBox.attr("y", boxY - boxHeight);
        backgroundBox.attr("width", 3 * boxWidth);
        backgroundBox.attr("height", 3 * boxHeight);

        backgroundBox.each(function () {
                this.parentNode.insertBefore(this, this.parentNode.firstChild);
        });

        if (imgWidth !== 0 && imgHeight !== 0) {
                let boxSizeScaleWidth = boxWidth / imgWidth;
                let boxSizeScaleHeight = boxHeight / imgHeight;
        
                if (boxSizeScaleWidth < boxSizeScaleHeight) {
                        g_markupsScale = boxSizeScaleWidth;
                        let viewImgHeight = imgHeight * boxSizeScaleWidth;
                        g_markupsOffsetHeight = (boxHeight - viewImgHeight) / 2;
                        g_markupsOffsetWidth = 0;
        
                        // markup_group
                        _self.markup_groups = _self.circles_group.append("g").attr("id", "g-markups"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                        _self.markup_groups = _self.circles_group.append("g").attr("transform", `translate(0, ${-g_markupsOffsetHeight}) scale(${g_markupsScale})`);
                        
                        _self.markup_groups_bottom.attr("transform", `translate(0, ${-g_markupsOffsetHeight}) scale(${g_markupsScale})`);
                } else {
                        g_markupsScale = boxSizeScaleHeight;
                        let viewImgWidth = imgWidth * boxSizeScaleHeight;
                        g_markupsOffsetWidth = (boxWidth - viewImgWidth) / 2;
                        g_markupsOffsetHeight = 0;
        
                        // markup_group
                        _self.markup_groups = _self.circles_group.append("g").attr("id", "g-markups"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                        _self.markup_groups = _self.circles_group.append("g").attr("transform", `translate(${g_markupsOffsetWidth}, 0) scale(${g_markupsScale})`);

                        _self.markup_groups_bottom.attr("transform", `translate(${g_markupsOffsetWidth}, 0) scale(${g_markupsScale})`);
                }
                _self.ballmarkup_groups = _self.circles_group.append("g").attr("id", "g-ball-markups"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                g_boxWidth = undefined;
                g_boxHeight = undefined;
        } else {
                // markup_group
                _self.markup_groups = _self.circles_group.append("g").attr("id", "g-markups"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                _self.ballmarkup_groups = _self.circles_group.append("g").attr("id", "g-ball-markups"); //创建一个g元素用来包裹svg文件去掉画布标签的其他标签内容
                g_markupsOffsetWidth = 0;
                g_markupsOffsetHeight = 0;

                // 保持用
                g_boxWidth = boxWidth;
                g_boxHeight = boxHeight;
        }
}

/**
 * 根据原版xml中的字体名 转换为字体代码，没有预置的字体名返回原字体名
 * @param {*} e 
 */
function checkFontIndexFromDefaultFontList(e) {
        for (var i = 0; i < g_FontImportCompareList.length; i++) {
                let temp = g_FontImportCompareList[i];
                if (e == temp.importName)
                        return temp.value;
        }
        return g_FontImportCompareList.slice(-1)[0].value
}

/**
 * 与checkFontIndexFromDefaultFontList相反，根据字体代码査找字体名称
 * @param {*} e 
 */
function checkFontNameFromDefaultFontList(e) {
        for (var i = 0; i < g_FontImportCompareList.length; i++) {
                let temp = g_FontImportCompareList[i];
                if (e == temp.value)
                        return temp.importName;
        }
        return g_FontImportCompareList.slice(-1)[0].importName;
}

/**
 * 全局参数设置，有选中markup元素，则更新
 * @param {*} e 
 */
function setGParams(e) {
        g_params = e;
        if (g_SelectedMarkup != null) {
                g_SelectedMarkup.updateParams(g_params);

                if (g_state == OPT_STATE.STATE_ADDING && (g_createShapeTypeId == 10 || g_createShapeTypeId == 11)) {
                        changeGlobalState(3, g_createShapeTypeId);
                        event.stopPropagation(); //阻止事件冒泡
                        event.preventDefault(); //阻止默认行为
                }
        }
}

/**
 * 清除选中状态
 */
function clearSelectedState() {
        if (g_SelectedMarkup != null) {
                g_SelectedMarkup.setSelected(false);
                g_SelectedMarkup = null;
        }

        // 可能有markup元素有选中ui，但没有选中状态标记
        for (var i = 0; i < g_markupList.length; i++) {
                let tempMarkup = g_markupList[i];
                if (tempMarkup.isSelected) {
                        tempMarkup.setSelectedJustUI(false);
                        tempMarkup.isSelected = false;
                }
        }

        // if (g_selectedCallBackFun)
        //   g_selectedCallBackFun(null);
}

/**
 * e 0 mormal  3 adding
 * @param {*} shapeTypeId 图形id
 * @param {*} params 参数 
 */
function changeGlobalState(stateid, shapeTypeId, isMarkupAfterConfirmed = false) {
        // var oldState = g_state;
        g_createShapeTypeId = shapeTypeId;
        if (stateid == 0) {
                g_state = OPT_STATE.STATE_NORMAL;
                isMarkupConfirmed = false; // 選択モードの時はfalseに戻す
        } else if (stateid == 3) {
                g_state = OPT_STATE.STATE_ADDING;
        }

        if (stateid === 0 && isMarkupAfterConfirmed) {
                return;
        }

        console.log(`changeGlobalState --- ${g_state} --- ${stateid} --- ${g_SelectedMarkup}`)
        if (stateid == 3 && g_SelectedMarkup && g_onAddMarkupDataFun) {
                g_onAddMarkupDataFun(g_SelectedMarkup.originData)
                isMarkupConfirmed = true;
        } else {
                clearSelectedState();
        }
}

/**
 * 加载成功后的回调
 * @param {*} inCallBack 
 */
function setLoadCallBack(inCallBack) {
        g_loadCallback = inCallBack;
}

/**
 * 元素选中后的回调
 * @param {*} inCallBack 
 */
function setSelectCallBack(inCallBack) {
        g_selectedCallBackFun = inCallBack;
}

/**
 * 打开外部文字输入ui的回调
 * @param {*} inCallBack 
 */
function setOpenInputTextCallBack(inCallBack) {
        g_openTextInputFun = inCallBack;
}

/**
 * 生成矩形包围盒数据
 * @param {*} shapePointList 坐标点列表
 * @param {*} blockWidth 控制点宽度
 * @param {*} strokeWidth 包围盒线宽
 */
function genNormalBoundingDotPositions(shapePointList, blockWidth, strokeWidth) {
        var re = {};
        var minX = d3.min(shapePointList, function (d) {
                return d.x;
        }),
                minY = d3.min(shapePointList, function (d) {
                        return d.y;
                }),
                maxX = d3.max(shapePointList, function (d) {
                        return d.x;
                }),
                maxY = d3.max(shapePointList, function (d) {
                        return d.y;
                });

        re.minX = minX;
        re.minY = minY;
        re.maxX = maxX;
        re.maxY = maxY;
        re.width = Math.abs(maxX - minX);
        re.height = Math.abs(maxY - minY);

        var width = Math.abs(maxX - minX);
        var height = Math.abs(maxY - minY);

        re.dotList = [{
                x: minX - blockWidth / 2 - strokeWidth,
                y: minY - blockWidth / 2 - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 0,
                style: "cursor:ne-resize"
        },
        {
                x: minX + width / 2 - blockWidth / 2 - strokeWidth,
                y: minY - blockWidth / 2 - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 1,
                style: "cursor:n-resize"
        },
        {
                x: minX + width - blockWidth / 2 - strokeWidth,
                y: minY - blockWidth / 2 - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 2,
                style: "cursor:nw-resize"
        },

        {
                x: minX - blockWidth / 2 - strokeWidth,
                y: minY + height / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 3,
                style: "cursor:w-resize"
        },
        {
                x: minX + width - blockWidth / 2 + strokeWidth,
                y: minY + height / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 4,
                style: "cursor:w-resize"
        },

        {
                x: minX - blockWidth / 2 - strokeWidth,
                y: minY + height + strokeWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 5,
                style: "cursor:nw-resize"
        },
        {
                x: minX + width / 2,
                y: minY + height + strokeWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 6,
                style: "cursor:n-resize"
        },
        {
                x: minX + width - blockWidth / 2 - strokeWidth,
                y: minY + height + strokeWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 7,
                style: "cursor:ne-resize"
        },
        ];
        return re;
}

/**
 * markup元素基类
 * MarkupBase  Markup 
 * @param {*} originData  外部传入的原始数据
 * @param {*} inTypeId 图形类型
 */
function MarkupBase(originData, inTypeId) {
        this.originData = originData;

        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        this.boundboxDots = [];
        this.typeId = inTypeId;
        var _MarkupBaseSelf = this;
        this.boundBoxShap = null; // 包围盒子
        this.contentShap = null;

        /**
         * 至于图纸下层，用于做图下填充
         */
        this.contentShapBottom = null;
        this.dotInfoList = []; // 包围盒 黑点

        if (g_layerList.length != 0) {
                if (typeof (originData.sLayId) == "undefined" && originData.sLayIndex >= 0) // sLayId 
                        this.sLayId = g_layerList[originData.sLayIndex].id;
                else
                        this.sLayId = originData.sLayId;
        }

        this.addGroups = function () {
                this.rootGroup = _self.markup_groups.append("g").attr("id", "g-markup" + this.typeName); // 标记根节点
                this.contentGroupBottom = _self.markup_groups_bottom.append("g").attr("id", "g-markup-bottom" + this.typeName); // 标记根节点

                this.contentGroup = this.rootGroup.append("g").attr("id", "g-content"); // 标记shap g
                this.boundboxGroup = this.rootGroup.append("g").attr("id", "g-boundbox"); // 标记包围g
        };

        /**
         * 内容的公共数据参数
         */
        this.apandBaseInfo = function () {
                console.log('this.originData', this.originData);
                var nRGBLColor = this.originData.selectedLineColor; // 线色
                var nRGBFillColor = this.originData.selectedFillColor; // 填充颜色
                var sFillType = this.originData.selectedFillType; // 填充类型 1 填充 2 填充  置于底层
                var sLineStyle = this.originData.selectedLineType; // 线型
                var wLineThick = this.originData.selectedLineWidth; // 线宽

                if (nRGBLColor) {
                        this.contentShap.attr("stroke", nRGBLColor);
                }

                if (wLineThick) {
                        this.contentShap.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
                }

                // fill
                {
                        var fillcolor = nRGBFillColor;
                        this.contentShap.attr("fill", sFillType == 2 ? fillcolor : "#00000000");
                        if (this.contentShapBottom != null)
                                this.contentShapBottom.attr("fill", sFillType == 2 ? fillcolor : "#00000000");
                }

                if (sLineStyle != null) {
                        this.contentShap.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
                }
        };

        this.addGroups();
        this.addContents();
        this.addBoundBoxContents();

        /**
         * 只设置选中ui，不改变全局选中item
         * @param {*} isS 
         */
        this.setSelectedJustUI = function (isS) {
                this.isSelected = isS;
                this.boundboxGroup.attr("visibility", isS ? "visible" : "hidden");

                // var sLineStyle = this.originData.selectedLineType; // 线型
                // var wLineThick = this.originData.selectedLineWidth; // 线宽
                // var nRGBFillColor = this.originData.selectedFillColor; // 填充颜色
                // var sFillType = this.originData.selectedFillType; // 填充类型 1 填充 2 填充  置于底层

                var nRGBLColor = this.originData.selectedLineColor; // 线色

                if (this.isSelected) {
                        this.contentShap.attr("stroke", g_ballMarkerSelectColor);
                        this.contentShapBottom.attr("stroke", g_ballMarkerSelectColor);
                } else {
                        this.contentShap.attr("stroke", nRGBLColor);
                        this.contentShapBottom.attr("stroke", nRGBLColor);
                }

        };

        /**
         * 图形内容点击事件
         */

        this.onShapeClick = function () {
                console.log(this, _MarkupBaseSelf)

                if (!g_canClickSelectMarkup)
                        return;

                if (g_canClickSelectMarkup && g_clickSelectExceptTypeList.indexOf(Number(_MarkupBaseSelf.typeId)) >= 0)
                        return;

                if (isMarkupConfirmed)
                        return;

                if (g_state == OPT_STATE.STATE_NORMAL) {
                        if (!_MarkupBaseSelf.isSelected || _MarkupBaseSelf.isSelected) {
                                clearSelectedState();
                                _MarkupBaseSelf.setSelected(true);
                                g_SelectedMarkup = _MarkupBaseSelf;
                        }
                }
        };

        /**
        * 图形内容鼠标划过
        */
        var beforeLeaveColor;

        this.onShapeMouseMove = function () {
                if (isMarkupConfirmed)
                        return;
                // console.log(g_SelectedMarkup)
                // console.log(!g_SelectedMarkup)
                // if (g_SelectedMarkup && d3.select(this)._groups[0][0] == g_SelectedMarkup.contentGroup._groups[0][0]) {
                //        return
                // }
                //记录原来的线段颜色
                beforeLeaveColor = d3.select(this).attr("stroke");
                if (beforeLeaveColor != "#ff0000aa") {
                        d3.select(this).attr("stroke", "blue");
                }
        };

        this.onShapeMouseLeave = function () {
                if (isMarkupConfirmed)
                        return;
                // if (d3.select(this)._groups[0][0] == g_SelectedMarkup.contentGroup._groups[0][0]) {
                //         return
                // }
                console.log(d3.select(this).attr("stroke"))
                if (d3.select(this).attr("stroke") == "#ff0000aa") {
                        return
                }
                d3.select(this).attr("stroke", beforeLeaveColor);

        };

        /**
         * 包围黑点 按下 
         * @param {*} index dot index 
         * @param {*} optType dot 类型  
         */
        this.onBoundBoxDotMouseDown = function (index) {
                if (!g_canEditSelectMarkup)
                        return;

                if (isMarkupConfirmed)
                        return;

                if (g_state == OPT_STATE.STATE_NORMAL) {
                        console.log("onBoundBoxDotMouseDown index = " + index);
                        g_state = OPT_STATE.STATE_CHANGING;
                        g_dotIndex = index;
                }
        }

        /**
         * 包围黑点 抬起
         * @param {*} index dot index 
         * @param {*} optType dot 类型
         */
        this.onBoundBoxDotMouseUp = function (index) {
                if (!g_canEditSelectMarkup)
                        return;

                if (isMarkupConfirmed)
                        return;


                if (g_onAddMarkupDataFun)
                        g_onAddMarkupDataFun(g_SelectedMarkup.originData)

                console.log("onBoundBoxDotMouseUp index = " + index);
                g_state = OPT_STATE.STATE_NORMAL;
                g_dotIndex = -1;
                // g_doRightClick = false;
        }

        /**
         * change状态下移动鼠标
         * @param {*} index dot index 
         * @param {*} optType dot 类型
         */
        this.onBoundBoxDotMouseMove = function (index) {
                if (!g_canEditSelectMarkup)
                        return;

                if (g_state != OPT_STATE.STATE_CHANGING)
                        return;

                if (isMarkupConfirmed)
                        return;

                var mouseosX = GetMousePositonOnSvgX();
                var mouseosY = GetMousePositonOnSvgY();

                // 更新
                this.updateDrawShape(index, mouseosX, mouseosY);
        };

        /**
         * 包围盒图形按下鼠标
         */
        this.onBoundBoxShapeMouseDown = function () {
                if (!g_canEditSelectMarkup)
                        return;

                if (isMarkupConfirmed)
                        return;

                // 开始移动位置
                if (g_state == OPT_STATE.STATE_NORMAL && this.isSelected) {
                        g_state = OPT_STATE.STATE_MOVING;
                        g_moveLastPos.x = GetMousePositonOnSvgX();
                        g_moveLastPos.y = GetMousePositonOnSvgY();
                }
        }

        /**
         * 包围盒图形抬起鼠标
         */
        this.onBoundBoxShapeMouseUp = function () {
                if (!g_canEditSelectMarkup)
                        return;

                if (isMarkupConfirmed)
                        return;

                if (g_onAddMarkupDataFun)
                        g_onAddMarkupDataFun(g_SelectedMarkup.originData)

                // 移动结束
                if (g_state == OPT_STATE.STATE_MOVING && this.isSelected) {
                        g_state = OPT_STATE.STATE_NORMAL;
                        // g_doRightClick = false;
                }
        }

        /**
         * 包围盒图形移动鼠标
         */
        this.onBoundBoxShapeMouseMove = function () {
                if (!g_canEditSelectMarkup)
                        return;

                if (isMarkupConfirmed)
                        return;

                if (g_state != OPT_STATE.STATE_MOVING)
                        return;
                // 移动位置
                var dx = GetMousePositonOnSvgX() - g_moveLastPos.x;
                var dy = GetMousePositonOnSvgY() - g_moveLastPos.y;
                this.updateDrawPosition(dx, dy);
                g_moveLastPos.x = GetMousePositonOnSvgX();
                g_moveLastPos.y = GetMousePositonOnSvgY();
        };

        /**
         * markup移动，更新点集中各个点的位置数据
         * @param {*} dx 
         * @param {*} dy 
         */
        this.updateDrawPosition = function (dx, dy) {
                for (var i = 0; i < this.originData.pointList.length; i++) {
                        this.originData.pointList[i].x = Number(this.originData.pointList[i].x) + dx;
                        this.originData.pointList[i].y = Number(this.originData.pointList[i].y) + dy;
                        this.addContents();
                        this.addBoundBoxContents();
                }
        };

        /**
         * 更新最后一个点的位置  矩形图形 重置左下点和右上点
         * @param {*} inPos 
         * @param {*} isEnd 
         */
        this.updateLastPosition = function (inPos, isEnd) {
                if (this.typeId != 8) {
                        this.originData.pointList[this.originData.pointList.length - 1].x = inPos.x;
                        this.originData.pointList[this.originData.pointList.length - 1].y = inPos.y;
                } else {
                        this.originData.pointList.push({
                                x: inPos.x,
                                y: inPos.y
                        });
                }

                if (isEnd) {
                        if (this.typeId == 4 || this.typeId == 5 || this.typeId == 6 || this.typeId == 10 || this.typeId == 12) {
                                var minx = Math.min(this.originData.pointList[0].x, this.originData.pointList[1].x);
                                var miny = Math.min(this.originData.pointList[0].y, this.originData.pointList[1].y);
                                var maxx = Math.max(this.originData.pointList[0].x, this.originData.pointList[1].x);
                                var maxy = Math.max(this.originData.pointList[0].y, this.originData.pointList[1].y);
                                this.originData.pointList[0] = {
                                        x: minx,
                                        y: miny
                                };
                                this.originData.pointList[1] = {
                                        x: maxx,
                                        y: maxy
                                };
                        }
                        if (this.doAtAddEnd != null)
                                this.doAtAddEnd();
                }
                this.addContents();
                this.addBoundBoxContents();
        };

        /**
         * 更新图形的基础参数
         * @param {*} params 
         */
        this.updateParams = function (params) {
                this.originData.selectedFont = params.selectedFont;
                this.originData.selectedFontSize = params.selectedFontSize;
                this.originData.selectedBold = params.selectedBold;
                this.originData.selectedItalics = params.selectedItalics;
                this.originData.selectedUnderline = params.selectedUnderline;
                this.originData.selectedLineType = params.selectedLineType;
                this.originData.selectedLineWidth = params.selectedLineWidth;
                this.originData.selectedLineColor = params.selectedLineColor;
                this.originData.selectedFillColor = params.selectedFillColor;
                this.originData.selectedFillType = params.selectedFillType;

                if (params.text)
                        this.originData.text = params.text;

                this.addContents();
                this.addBoundBoxContents();
        };

        // 点击选中
        if (this.boundBoxShap)
                this.boundBoxShap.on("click", this.onShapeClick)
        // this.boundBoxShap.on("mouseenter", this.onShapeMouseMove)
        if (this.contentGroup)
                this.contentGroup.on("click", this.onShapeClick)
        if (this.contentGroupBottom)
                this.contentGroupBottom.on("click", this.onShapeClick)

        if (isMouseMove) {
                this.contentGroup.on("mouseenter", this.onShapeMouseMove)
                this.contentGroup.on("mouseleave", this.onShapeMouseLeave)
        }

}

/**
 * 绘制包围盒及包围盒控制点
 */
MarkupBase.prototype.addBoundBoxContents = function () {
        console.log("base addBoundBoxContents");
        var _MarkupBaseSelf = this;
        var strokeWidth = 0;
        var blockWidth = g_editDotWidth;

        var dotpointsList = genNormalBoundingDotPositions(
                this.originData.pointList,
                blockWidth,
                strokeWidth
        )

        var minX = dotpointsList.minX;
        var minY = dotpointsList.minY;
        var width = dotpointsList.width;
        var height = dotpointsList.height;
        this.dotInfoList = dotpointsList.dotList;

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
        }

        this.boundBoxShap
                .attr("x", minX)
                .attr("y", minY)
                .attr("width", width)
                .attr("height", height)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000099")
                .attr("stroke-opacity", "0")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);

        // 开始移动位置
        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        // 结束移动位置
        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);

                if (d3.event.button != 0) {
                        g_doRightClick = false;
                }
        });

        for (var i = 0; i < this.dotInfoList.length; i++) {
                var tempDotInfo = this.dotInfoList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect").attr("stroke-width", "0.07");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        /**
                         * optType: 0随便动 1上下 2 左右
                         */
                        dotInfoLeftBottom.optType = tempDotInfo.optType;

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                if (d3.event.button != 0)
                                        return;
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.attr("style", tempDotInfo.style);
                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x)
                        .attr("y", tempDotInfo.y)
                        .attr("width", tempDotInfo.width)
                        .attr("height", tempDotInfo.height)
                        .attr("stroke", tempDotInfo.stroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", tempDotInfo.fill);
        }
};

/**
 * 设置选中ui和状态
 * @param {*} isS 
 * @param {*} shouldCallBack 
 */
MarkupBase.prototype.setSelected = function (isS, shouldCallBack = true) {
        g_SelectedMarkup = this;
        this.isSelected = isS;
        // this.boundBoxShap.attr("stroke", isS ? "#00000033" : "#00000000")
        console.log(this)
        // this.boundboxGroup.attr("visibility", isS ? "visible" : "hidden");
        this.setSelectedJustUI(isS);

        if (isS && g_selectedCallBackFun && shouldCallBack)
                g_selectedCallBackFun(g_SelectedMarkup.originData);
};

/**
 * 新增markup元素结束环节执行回调
 */
MarkupBase.prototype.doAtAddEnd = function () {
        console.log("MarkupBase.doAtAddEnd")
}

/**
 * markup元素-矩形
 * Markup draw a Rect
 * @param {*} originData 
 * @param {*} inTypeId  4 矩形（默认不填充）  5 矩形（默认填充）
 */
function MarkupRect(originData, inTypeId) {
        console.log(originData, inTypeId, "RRRRRRRRRRRRRRR")
        this.typeName = 'MarkupRect';
        MarkupBase.call(this, originData, inTypeId);
}

MarkupRect.prototype.addContents = function () {
        var point1 = this.originData.pointList[0]; // 点1
        var point2 = this.originData.pointList[1]; // 点2

        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("rect"); // 标记 shape

        if (this.contentShapBottom == null)
                this.contentShapBottom = this.contentGroupBottom.append("rect"); // 标记 shape

        this.contentShap
                .attr("id", "content")
                .attr("stroke-width", '1')
                .attr("x", function () {
                        return Math.min(point1.x, point2.x)
                })
                .attr("y", function () {
                        return Math.min(point1.y, point2.y);
                })
                .attr("width", function () {
                        return Math.abs(point1.x - point2.x)
                })
                .attr("height", function () {
                        return Math.abs(point1.y - point2.y)
                });

        this.contentShapBottom
                .attr("id", "content")
                .attr("stroke-width", '0.05')
                .attr("x", function () {
                        return Math.min(point1.x, point2.x)
                })
                .attr("y", function () {
                        return Math.min(point1.y, point2.y);
                })
                .attr("width", function () {
                        return Math.abs(point1.x - point2.x)
                })
                .attr("height", function () {
                        return Math.abs(point1.y - point2.y)
                });

        this.apandBaseInfo();
        // this.contentShap.attr("visibility", "hidden");
        var nRGBLColor = this.originData.selectedLineColor; // 线色

        if (this.isSelected) {
                this.contentShap.attr("stroke", g_ballMarkerSelectColor);
                this.contentShapBottom.attr("stroke", g_ballMarkerSelectColor);
        } else {
                this.contentShap.attr("stroke", nRGBLColor);
                this.contentShapBottom.attr("stroke", nRGBLColor);
        }

};




/**
 * 包围盒及黑顶绘制 
 */
MarkupRect.prototype.addBoundBoxContents = MarkupBase.prototype.addBoundBoxContents
MarkupRect.prototype.setSelected = MarkupBase.prototype.setSelected

/**
 * changing状态改变图形形状  
 * @param {*} index 
 * @param {*} mouseosX 
 * @param {*} mouseosY 
 */
MarkupRect.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        var dotInfo = this.boundboxDots[index];
        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        if (dotInfo.optType == 0) {
                if (mouseosY > this.originData.pointList[1].y - g_markupLineWidth ||
                        mouseosX > this.originData.pointList[1].x - g_markupLineWidth)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 1) {
                if (mouseosY > this.originData.pointList[1].y - g_markupLineWidth)
                        return;

                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 2) {
                if (mouseosY > this.originData.pointList[1].y - g_markupLineWidth ||
                        mouseosX < this.originData.pointList[0].x + g_markupLineWidth)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 3) {
                if (mouseosX > this.originData.pointList[1].x - g_markupLineWidth)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 4) {
                if (mouseosX < this.originData.pointList[0].x + g_markupLineWidth)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 5) {
                if (mouseosX > this.originData.pointList[1].x - g_markupLineWidth ||
                        mouseosY < this.originData.pointList[0].y + g_markupLineWidth)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 6) {
                if (mouseosY < this.originData.pointList[0].y + g_markupLineWidth)
                        return;

                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 7) {
                if (mouseosX < this.originData.pointList[0].x + g_markupLineWidth ||
                        mouseosY < this.originData.pointList[0].y + g_markupLineWidth)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a Line
 * @param {*} originData 
 * type  1  线段  2 多段线 3 多边形 8 自由画线
 */
function MarkupLine(originData, inTypeId) {
        this.typeName = 'MarkupLine';
        MarkupBase.call(this, originData, inTypeId);
}

MarkupLine.prototype.addContents = function () {
        var _self = this;
        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("path"); // 标记 shape
        if (this.contentShapBottom == null)
                this.contentShapBottom = this.contentGroupBottom.append("path"); // 标记 shape


        this.contentShap
                .attr("id", "content")
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.originData.pointList.length; i++) {
                                var temppos = _self.originData.pointList[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.x + " " + temppos.y;
                        }

                        if (_self.typeId == "3")
                                re += " Z";
                        return re;
                });

        if (this.typeId == 3) {
                this.contentShapBottom
                        .attr("id", "content")
                        .attr("d", function () {
                                var re = "M";
                                for (var i = 0; i < _self.originData.pointList.length; i++) {
                                        var temppos = _self.originData.pointList[i];
                                        if (i != 0)
                                                re += " L ";
                                        re += temppos.x + " " + temppos.y;
                                }

                                if (_self.typeId == "3")
                                        re += " Z";
                                return re;
                        })
                        .attr("stroke-width", "0.01");
        } else {
                this.originData.selectedFillType = 0;
        }
        this.apandBaseInfo();

        var nRGBLColor = this.originData.selectedLineColor; // 线色

        if (this.isSelected) {
                this.contentShap.attr("stroke", g_ballMarkerSelectColor);
                this.contentShapBottom.attr("stroke", g_ballMarkerSelectColor);
        } else {
                this.contentShap.attr("stroke", nRGBLColor);
                this.contentShapBottom.attr("stroke", nRGBLColor);
        }
};

/**
 * 包围盒及黑顶绘制 
 */
MarkupLine.prototype.addBoundBoxContents = function () {
        var _MarkupBaseSelf = this;
        var strokeWidth = 0;
        var blockWidth = g_editDotWidth;

        var dotpointsList = genNormalBoundingDotPositions(
                this.originData.pointList,
                blockWidth,
                strokeWidth
        )

        var minX = dotpointsList.minX;
        var minY = dotpointsList.minY;
        var width = dotpointsList.width;
        var height = dotpointsList.height;

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
        }

        this.boundBoxShap
                .attr("x", minX - blockWidth - strokeWidth)
                .attr("y", minY - blockWidth - strokeWidth)
                .attr("width", width + blockWidth * 2 + strokeWidth * 2)
                .attr("height", height + blockWidth * 2 + strokeWidth * 2)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000033")
                .attr("stroke-opacity", "0")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);

        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为

                if (d3.event.button != 0) {
                        g_doRightClick = false;
                }
        });

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempDotInfo = this.originData.pointList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        dotInfoLeftBottom.optType = i;

                        tempDotShape.attr("style", "cursor:ne-resize");

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.on("mouseup", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseUp(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x - g_editDotWidth / 2)
                        .attr("y", tempDotInfo.y - g_editDotWidth / 2)
                        .attr("width", g_editDotWidth)
                        .attr("height", g_editDotWidth)
                        .attr("stroke", g_editDotStroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", g_editDotFill);
        }
};
MarkupLine.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupLine.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        if (index < this.originData.pointList.length) {
                this.originData.pointList[index].x = mouseosX;
                this.originData.pointList[index].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a ellipse
 * @param {*} originData 
 * type  1  线段  2 多段线 3 多边形
 */
function MarkupEllipse(originData, inTypeId) {
        this.typeName = 'MarkupEllipse';
        MarkupBase.call(this, originData, inTypeId);
}


// cx="300" cy="150" rx="200" ry="80"
MarkupEllipse.prototype.addContents = function () {
        var point1 = this.originData.pointList[0]; // 点1
        var point2 = this.originData.pointList[1]; // 点2

        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("ellipse"); // 标记 shape

        if (this.contentShapBottom == null)
                this.contentShapBottom = this.contentGroupBottom.append("ellipse"); // 标记 shape

        this.contentShap
                .attr("cx", function () {
                        return point1.x + (point2.x - point1.x) / 2;
                })
                .attr("cy", function () {
                        return point1.y + (point2.y - point1.y) / 2;
                })
                .attr("rx", function () {
                        return Math.abs((point2.x - point1.x) / 2);
                })
                .attr("ry", function () {
                        return Math.abs((point2.y - point1.y) / 2);
                });

        this.contentShapBottom
                .attr("cx", function () {
                        return point1.x + (point2.x - point1.x) / 2;
                })
                .attr("cy", function () {
                        return point1.y + (point2.y - point1.y) / 2;
                })
                .attr("rx", function () {
                        return Math.abs((point2.x - point1.x) / 2);
                })
                .attr("ry", function () {
                        return Math.abs((point2.y - point1.y) / 2);
                });

        this.apandBaseInfo();
};

/**
 * 包围盒及黑顶绘制 
 */
MarkupEllipse.prototype.addBoundBoxContents = MarkupBase.prototype.addBoundBoxContents
MarkupEllipse.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupEllipse.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        var dotInfo = this.boundboxDots[index];
        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        if (dotInfo.optType == 0) {
                if (mouseosY > this.originData.pointList[1].y - 10 || mouseosX > this.originData.pointList[1].x - 10)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 1) {
                if (mouseosY > this.originData.pointList[1].y - 10)
                        return;

                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 2) {
                if (mouseosY > this.originData.pointList[1].y - 10 || mouseosX < this.originData.pointList[0].x + 10)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 3) {
                if (mouseosX > this.originData.pointList[1].x - 10)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 4) {
                if (mouseosX < this.originData.pointList[0].x + 10)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 5) {
                if (mouseosX > this.originData.pointList[1].x - 10 || mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 6) {
                if (mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 7) {
                if (mouseosX < this.originData.pointList[0].x + 10 || mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a Arc
 * @param {*} originData 
 * type  1  线段  2 多段线 3 多边形
 */
function MarkupArc(originData, inTypeId) {
        this.typeName = 'MarkupArc';
        MarkupBase.call(this, originData, inTypeId);
}

// cx="300" cy="150" rx="200" ry="80"
MarkupArc.prototype.addContents = function () {
        /**
         * 平面三点定位算法
         * @param {*} x1 
         * @param {*} y1 
         * @param {*} x2 
         * @param {*} y2 
         * @param {*} x3 
         * @param {*} y3 
         */

        if (this.originData.pointList.length < 3)
                return;

        var centerInCircle = function (x1, y1, x2, y2, x3, y3) {
                var a;
                a = (y2 - y1) / (x2 - x1);
                var xMiddle = (x1 + x2) / 2;
                var yMiddle = (y1 + y2) / 2;
                var c, lastX, lastY;
                if (a != 0) {
                        c = yMiddle - (-1 / a) * xMiddle;
                        lastX = (Math.pow(x1, 2) + Math.pow(y1, 2) - Math.pow(x3, 2) - Math.pow(y3, 2) - 2 * c * y1 + 2 * c * y3) / (2 * ((x1 - x3) - (1 / a) * (y1 - y3)));
                        lastY = (-1 / a) * lastX + c;
                } else {
                        lastX = c = xMiddle;
                        lastY = (Math.pow(x1, 2) + Math.pow(y1, 2) - Math.pow(x3, 2) - Math.pow(y3, 2) + 2 * lastX * (x3 - x1)) / (2 * (y1 - y3));
                }
                return {
                        x: lastX,
                        y: lastY
                }
        }
        var point1 = this.originData.pointList[0]; // 点1
        var point2 = this.originData.pointList[1]; // 点2
        var point3 = this.originData.pointList[2]; // 点3

        // 1、2中点
        var pointC12 = {
                x: (point1.x + point2.x) / 2,
                y: (point1.y + point2.y) / 2
        };
        // var pointC13 = { x: (point1.x + point3.x) / 2, y: (point1.y + point3.y) / 2 };
        // var pointC23 = { x: (point3.x + point2.x) / 2, y: (point3.y + point2.y) / 2 };

        // 圆心
        var circleCenter = centerInCircle(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y);
        // 半径
        var circleRadius = Math.sqrt(Math.pow(point1.x - circleCenter.x, 2) + Math.pow(point1.y - circleCenter.y, 2));

        var dis3ToC12 = Math.sqrt(Math.pow(point3.x - pointC12.x, 2) + Math.pow(point3.y - pointC12.y, 2));
        var halfDis12 = Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)) / 2;

        var isBigArc = dis3ToC12 > halfDis12 ? 1 : 0;


        var str = "M" + point1.x + " " + point1.y + " ";
        str += "A " + circleRadius + " " + circleRadius + " "; // 长短半径
        str += 0 + " "; // x-axis-rotation  旋转
        str += isBigArc + " "; // large-arc-flag  大小弧 0 小弧度
        str += 0 + " "; // sweep-flag  方向 0 逆时针
        str += point2.x + " " + point2.y + " ";

        if (this.originData.selectedFillType != 0)
                str += "Z";

        this.contentShap
        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("path") // 标记 shape

        if (this.contentShapBottom == null)
                this.contentShapBottom = this.contentGroupBottom.append("path") // 标记 shape

        this.contentShap
                .attr("d", str);

        this.contentShapBottom
                .attr("d", str);

        this.apandBaseInfo();
};

/**
 * 包围盒及黑顶绘制 
 */
MarkupArc.prototype.addBoundBoxContents = function () {
        var _MarkupBaseSelf = this;

        if (this.contentShap != null) {
                this.contentShap.on("mousedown", function () {
                        var dataindex = d3.select(this).attr("dataIndex");
                        _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                        event.stopPropagation(); //阻止事件冒泡
                        event.preventDefault(); //阻止默认行为
                });

                this.contentShap.on("mouseup", function () {
                        var dataindex = d3.select(this).attr("dataIndex");
                        _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);
                        event.stopPropagation(); //阻止事件冒泡
                        event.preventDefault(); //阻止默认行为
                });

        }

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempDotInfo = this.originData.pointList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        dotInfoLeftBottom.optType = i;

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.on("mouseup", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseUp(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.attr("style", "cursor:ne-resize");

                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x - g_editDotWidth / 2)
                        .attr("y", tempDotInfo.y - g_editDotWidth / 2)
                        .attr("width", g_editDotWidth)
                        .attr("height", g_editDotWidth)
                        .attr("stroke", g_editDotStroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", g_editDotFill);
        }
}
MarkupArc.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupArc.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        if (index < this.originData.pointList.length) {
                this.originData.pointList[index].x = mouseosX;
                this.originData.pointList[index].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a text
 * @param {*} originData 
 * type  10 文字
 */
function MarkupText(originData, inTypeId) {
        this.typeName = 'MarkupText';
        MarkupBase.call(this, originData, inTypeId);
}

function getStringLength(str) {
        var slength = 0;
        for (var i = 0; i < str.length; i++) {
                if ((str.charCodeAt(i) >= 0) && (str.charCodeAt(i) <= 255))
                        slength = slength + 1;
                else
                        slength = slength + 2;
        }
        return slength;
}

MarkupText.prototype.addContents = function () {
        var _self = this;
        var point1 = this.originData.pointList[0]; // 点1
        var point2 = this.originData.pointList[1]; // 点2
        // var reCalShape = false;

        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("text") // 标记 shape

        /**
         * 如果换了字体、文字内容、字号，需要重新计算文字整体宽高
         */
        console.log(this.contentShap.attr("font-family"))
        console.log(this.contentShap.attr("lastTest"))
        console.log(this.contentShap.attr("font-size"))


        if ((this.contentShap.attr("font-family") && this.contentShap.attr("font-family") != this.originData.selectedFont) ||
                (this.contentShap.attr("lastTest") && this.contentShap.attr("lastTest") != this.originData.text) ||
                (this.contentShap.attr("font-size") && this.contentShap.attr("font-size") > this.originData.selectedFontSize * g_markupTextDefaultWidth * 1.1) ||
                (this.contentShap.attr("font-size") && this.contentShap.attr("font-size") < this.originData.selectedFontSize * g_markupTextDefaultWidth * 0.9)
        ) {
                this.originData.fontWidth = this.originData.selectedFontSize;
        }

        // var lastFontSize = this.contentShap.attr("font-size");
        // var lastFontStr = this.contentShap.attr("lastTest");
        var fontWidth = this.originData.fontWidth * g_markupTextDefaultWidth;
        // var fontHeight = this.originData.selectedFontSize * g_markupTextDefaultWidth;

        this.contentShap
                // .text(re_str)
                .attr("x", 0)
                .attr("y", 0)
                .attr("fill", this.originData.selectedLineColor)
                .attr("font-size", this.originData.selectedFontSize * g_markupTextDefaultWidth) // 字体大小
                .attr("lengthAdjust", "spacingAndGlyphs") // spacing  空间平均分配到文字间
                .attr("dominant-baseline", "ideographic") // 调整文字的基线
                .attr("text-decoration", this.originData.selectedUnderline ? "underline" : "none") // 下划线
                .attr("font-style", this.originData.selectedItalics ? "italic" : "normal") // 斜体
                .attr("font-weight", this.originData.selectedBold ? "bold" : "normal") // 粗体
                .attr("font-family", this.originData.selectedFont) // 字体
                .attr("lastTest", this.originData.text) // 字体

        // multi lines cut
        // 如果内容改变、字号改变   重新分割字符串，计算字符宽度
        var wholeWidthCharSum = 0; // 半角字符长度

        this.contentShap.selectAll("tspan").each(function () {
                d3.select(this).remove();
        })

        var temptext = this.originData.text;
        var texttips = temptext.split("\n");

        for (var i = 0; i < texttips.length; i++) {
                // re_str += "<tspan>" + texttips[i] + "</tspan>";
                this.contentShap.append("tspan").text(texttips[i])
                        .attr('x', 0)
                        .attr('y', 0 - (texttips.length - 1 - i) * this.originData.selectedFontSize * g_markupTextDefaultWidth);
                if (getStringLength(texttips[i]) > wholeWidthCharSum)
                        wholeWidthCharSum = getStringLength(texttips[i]);
        }

        this.originData.wholeWidthCharSum = wholeWidthCharSum;

        // multi lines cut end

        var wholeWidth = wholeWidthCharSum * fontWidth / 2;

        var box1 = this.contentShap._groups;
        var box11 = box1[0][0];
        var boxx = box11.getBBox();

        this.originData.pointList[1] = {
                x: point1.x + boxx.width,
                y: point1.y + boxx.height
        };

        point2 = this.originData.pointList[1];

        this.contentShap.attr("transform", function () {
                var ratio = wholeWidth / Math.abs(point1.x - point2.x);
                var scalex = ratio;
                var scaley = -1;
                var minx = Math.min(point1.x, point2.x) / ratio;
                var miny = Math.min(point1.y, point2.y) - Math.abs(point1.y - point2.y);

                var str = '';
                str += "scale(" + scalex + "," + scaley + ") ";
                str += "translate(" + minx + "," + (0 - miny) + ")";

                _self.originData.pointList[1].x = Math.min(point1.x, point2.x) + Math.abs(point1.x - point2.x) * ratio;

                return str;
        })
};

/**
 * 包围盒及黑顶绘制 
 */
MarkupText.prototype.addBoundBoxContents = function () {
        var _MarkupBaseSelf = this;
        var strokeWidth = 0;
        var blockWidth = g_editDotWidth;

        var dotpointsList = genNormalBoundingDotPositions(
                this.originData.pointList,
                blockWidth,
                strokeWidth
        )

        var minX = dotpointsList.minX;
        var minY = dotpointsList.minY;
        var maxY = dotpointsList.maxY;
        minY = minY - Math.abs(maxY - minY);
        var width = dotpointsList.width;
        var height = dotpointsList.height;
        this.dotInfoList = dotpointsList.dotList;

        for (var i = 0; i < this.dotInfoList.length; i++) {
                if (i != 3 && i != 4)
                        this.dotInfoList[i].width = this.dotInfoList[0].height = 0;
                this.dotInfoList[i].y -= height;
        }

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
                this.boundBoxShap.on("dblclick", function () {
                        g_openTextInputFun(_MarkupBaseSelf.originData.text);
                        event.stopPropagation(); //阻止事件冒泡
                        event.preventDefault(); //阻止默认行为
                })
        }

        this.boundBoxShap
                .attr("x", minX)
                .attr("y", minY)
                .attr("width", width)
                .attr("height", height)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000099")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);


        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);

                if (d3.event.button != 0) {
                        g_doRightClick = false;
                }
        });

        for (var i = 0; i < this.dotInfoList.length; i++) {
                var tempDotInfo = this.dotInfoList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        /**
                         * optType: 0随便动 1上下 2 左右
                         */
                        dotInfoLeftBottom.optType = tempDotInfo.optType;

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                if (d3.event.button != 0)
                                        return;
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.attr("style", tempDotInfo.style);
                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x)
                        .attr("y", tempDotInfo.y)
                        .attr("width", tempDotInfo.width)
                        .attr("height", tempDotInfo.height)
                        .attr("stroke", tempDotInfo.stroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", tempDotInfo.fill);
        }
}
MarkupText.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupText.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        var dotInfo = this.boundboxDots[index];
        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        if (dotInfo.optType == 0) {
                if (mouseosY > this.originData.pointList[1].y - 10 || mouseosX > this.originData.pointList[1].x - 10)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 1) {
                if (mouseosY > this.originData.pointList[1].y - 10)
                        return;

                Math.min(this.originData.pointList[0].y, this.originData.pointList[1].y) == this.originData.pointList[0].y ?
                        this.originData.pointList[0].y = mouseosY : this.originData.pointList[1].y = mouseosY;


                // this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 2) {
                if (mouseosY > this.originData.pointList[1].y - 10 || mouseosX < this.originData.pointList[0].x + 10)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[0].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 3) {
                if (mouseosX > this.originData.pointList[1].x - 10)
                        return;

                Math.min(this.originData.pointList[0].x, this.originData.pointList[1].x) == this.originData.pointList[0].x ?
                        this.originData.pointList[0].x = mouseosX : this.originData.pointList[1].x = mouseosX;

                let wholeWidthCharSum = this.originData.wholeWidthCharSum;
                let widthGap = Math.abs(this.originData.pointList[0].x - this.originData.pointList[1].x);
                let fontWidthValue = widthGap * 2 / wholeWidthCharSum;

                // this.originData.fontWidth * 0.5 * g_markupLineWidth * 10
                this.originData.fontWidth = fontWidthValue / g_markupTextDefaultWidth;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 4) {
                if (mouseosX < this.originData.pointList[0].x + 10)
                        return;
                Math.max(this.originData.pointList[0].x, this.originData.pointList[1].x) == this.originData.pointList[0].x ?
                        this.originData.pointList[0].x = mouseosX : this.originData.pointList[1].x = mouseosX;

                let wholeWidthCharSum = this.originData.wholeWidthCharSum;
                let widthGap = Math.abs(this.originData.pointList[0].x - this.originData.pointList[1].x);
                let fontWidthValue = widthGap * 2 / wholeWidthCharSum;

                // this.originData.fontWidth * 0.5 * g_markupLineWidth * 10
                this.originData.fontWidth = fontWidthValue / g_markupTextDefaultWidth;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 5) {
                if (mouseosX > this.originData.pointList[1].x - 10 || mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[0].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 6) {
                if (mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        } else if (dotInfo.optType == 7) {
                if (mouseosX < this.originData.pointList[0].x + 10 || mouseosY < this.originData.pointList[0].y + 10)
                        return;

                this.originData.pointList[1].x = mouseosX;
                this.originData.pointList[1].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a Draw
 * @param {*} originData 
 * type 8 自由画线 9 cloud
 */
function MarkupHandDraw(originData, inTypeId) {
        this.typeName = 'MarkupHandDraw';
        MarkupBase.call(this, originData, inTypeId);
}

MarkupHandDraw.prototype.addContents = function () {
        var _self = this;
        if (this.contentShap == null)
                this.contentShap = this.contentGroup.append("path"); // 标记 shape

        this.contentShap
                .attr("id", "content")
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.originData.pointList.length; i++) {
                                var temppos = _self.originData.pointList[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.x + " " + temppos.y;
                        }
                        return re;
                });

        _self.originData.selectedFillType = 0;
        this.apandBaseInfo();
};

/**
 * 包围盒及黑点绘制 
 */
MarkupHandDraw.prototype.addBoundBoxContents = function () {

        var minX = d3.min(this.originData.pointList, function (d) {
                return d.x;
        }),
                minY = d3.min(this.originData.pointList, function (d) {
                        return d.y;
                }),
                maxX = d3.max(this.originData.pointList, function (d) {
                        return d.x;
                }),
                maxY = d3.max(this.originData.pointList, function (d) {
                        return d.y;
                });
        var _MarkupBaseSelf = this;
        var width = Math.abs(maxX - minX);
        var height = Math.abs(maxY - minY);
        var strokeWidth = 0;

        /**
   * 盒子上黑点的数据 
   * 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
   * 
   * var g_editDotStroke = "#000000"; // 包围盒黑点宽度
var g_editDotFill = "#000000"; // 包围盒黑点宽度
 
   */
        var blockWidth = g_editDotWidth;
        this.dotInfoList = [{
                x: minX - blockWidth - strokeWidth,
                y: minY - blockWidth - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 0
        },
        {
                x: minX + width / 2,
                y: minY - blockWidth - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 1
        },
        {
                x: minX + width + strokeWidth,
                y: minY - blockWidth - strokeWidth,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 2
        },

        {
                x: minX - blockWidth - strokeWidth,
                y: minY + height / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 3
        },
        {
                x: minX + width + strokeWidth,
                y: minY + height / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 4
        },

        {
                x: minX - blockWidth - strokeWidth,
                y: minY + height + strokeWidth + g_editDotWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 5
        },
        {
                x: minX + width / 2,
                y: minY + height + strokeWidth + g_editDotWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 6
        },
        {
                x: minX + width + strokeWidth,
                y: minY + height + strokeWidth + g_editDotWidth - blockWidth / 2,
                width: blockWidth,
                height: blockWidth,
                stroke: g_editDotStroke,
                fill: g_editDotStroke,
                optType: 7
        },
        ];

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
        }

        this.boundBoxShap
                .attr("x", minX - blockWidth - strokeWidth)
                .attr("y", minY - blockWidth - strokeWidth)
                .attr("width", width + blockWidth * 2 + strokeWidth * 2)
                .attr("height", height + blockWidth * 2 + strokeWidth * 2)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000033")
                .attr("stroke-opacity", "0")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);

        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
                if (d3.event.button != 0) {
                        g_doRightClick = false;
                }
        });

        for (var i = 0; i < this.dotInfoList.length; i++) {
                var tempDotInfo = this.dotInfoList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        /**
                         * optType: 0随便动 1上下 2 左右
                         */
                        dotInfoLeftBottom.optType = tempDotInfo.optType;

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x)
                        .attr("y", tempDotInfo.y)
                        .attr("width", tempDotInfo.width)
                        .attr("height", tempDotInfo.height)
                        .attr("stroke", tempDotInfo.stroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", tempDotInfo.fill);
        }
}
MarkupHandDraw.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupHandDraw.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        var dotInfo = this.boundboxDots[index];
        var minX = d3.min(this.originData.pointList, function (d) {
                return d.x;
        }),
                minY = d3.min(this.originData.pointList, function (d) {
                        return d.y;
                }),
                maxX = d3.max(this.originData.pointList, function (d) {
                        return d.x;
                }),
                maxY = d3.max(this.originData.pointList, function (d) {
                        return d.y;
                });

        var widthO = Math.abs(maxX - minX);
        var heightO = Math.abs(maxY - minY);
        var widthN = 1;
        var heightN = 1;
        var minXN = 1;
        var minYN = 1;
        var maxXN = 1;
        var maxYN = 1;

        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        if (dotInfo.optType == 0) {
                if (mouseosY > maxY - 10 || mouseosX > maxX - 10)
                        return;
                minXN = mouseosX;
                minYN = mouseosY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 1) {
                if (mouseosY > maxY - 10)
                        return;

                minXN = minX;
                minYN = mouseosY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 2) {
                if (mouseosY > maxY - 10 || mouseosX < minX + 10)
                        return;

                minXN = minX;
                minYN = mouseosY;
                maxXN = mouseosX;
                maxYN = maxY;
        } else if (dotInfo.optType == 3) {
                if (mouseosX > maxX - 10)
                        return;

                minXN = mouseosX;
                minYN = minY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 4) {
                if (mouseosX < minX + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = mouseosX;
                maxYN = maxY;
        } else if (dotInfo.optType == 5) {
                if (mouseosX > maxX - 10 || mouseosY < minY + 10)
                        return;

                minXN = mouseosX;
                minYN = minY;
                maxXN = maxX;
                maxYN = mouseosY;
        } else if (dotInfo.optType == 6) {
                if (mouseosY < minY + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = maxX;
                maxYN = mouseosY;
        } else if (dotInfo.optType == 7) {
                if (mouseosX < minX + 10 || mouseosY < minY + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = mouseosX;
                maxYN = mouseosY;
        }
        widthN = maxXN - minXN;
        heightN = maxYN - minYN;

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempPoint = this.originData.pointList[i];
                var xN = (((tempPoint.x - minX) / widthO) * widthN) + minXN;
                var yN = (((tempPoint.y - minY) / heightO) * heightN) + minYN;

                tempPoint.x = xN;
                tempPoint.y = yN;
        }
        this.addContents();
        this.addBoundBoxContents();
};

///////////////////////////////////////////////////
/**
 * Markup draw a Draw
 * @param {*} originData 
 * type 9 cloud
 */
function MarkupCloudDraw(originData, inTypeId) {
        this.arcShapes = [null, null, null, null, null, null];
        this.polyShape = null;
        this.arcShapesBottom = [null, null, null, null, null, null];
        this.polyShapeBottom = null;
        this.arcCDatas = null;

        this.typeName = 'MarkupCloudDraw';
        MarkupBase.call(this, originData, inTypeId);
}
MarkupCloudDraw.prototype.addContents = function () {
        var _self = this;
        var point1 = this.originData.pointList[0]; // 点1
        var point2 = this.originData.pointList[1]; // 点2
        var widthWhole = Math.abs(point1.x - point2.x);
        var heightWhole = Math.abs(point1.y - point2.y);

        var MINX = Math.min(point1.x, point2.x) - widthWhole * 0.0;
        var MINY = Math.min(point1.y, point2.y) - heightWhole * 0.0;
        var MAXX = Math.max(point1.x, point2.x) + widthWhole * 0.0;
        var MAXY = Math.max(point1.y, point2.y) + heightWhole * 0.0;

        var internalgap = Math.min(widthWhole, heightWhole) / 3.5;

        var minX = Math.min(point1.x, point2.x) + internalgap;
        var minY = Math.min(point1.y, point2.y) + internalgap;
        var maxX = Math.max(point1.x, point2.x) - internalgap;
        var maxY = Math.max(point1.y, point2.y) - internalgap;

        var width = Math.abs(minX - maxX);
        var height = Math.abs(minY - maxY);
        var O = {
                x: minX + width / 2,
                y: minY + height / 2
        };

        _self.arcCDatas = [{ // 0
                startPos: {
                        x: maxX,
                        y: O.y + height / 4
                },
                endPos: {
                        x: O.x,
                        y: maxY
                },
                controllPos: [{
                        // x: maxX, y: MAXY
                        x: maxX + (MAXX / 2 - maxX / 2),
                        y: O.y + height * 0.75
                },
                {
                        x: O.x,
                        y: MAXY
                },
                ]
        }, { // 1
                startPos: {
                        x: O.x,
                        y: maxY,
                },
                endPos: {
                        x: minX,
                        y: O.y + height / 4
                },
                controllPos: [{
                        x: O.x,
                        y: MAXY
                },
                {
                        x: minX - (MAXX / 2 - maxX / 2),
                        y: O.y + height * 0.75
                },
                ]
        }, { // 2
                startPos: {
                        x: minX,
                        y: O.y + height / 4
                },
                endPos: {
                        x: minX,
                        y: O.y - height / 4,
                },
                controllPos: [{
                        x: MINX,
                        y: O.y + height / 2.2
                },
                {
                        x: MINX,
                        y: O.y - height / 2.2
                },
                ]
        }, { // 3
                startPos: {
                        x: minX,
                        y: O.y - height / 4
                },
                endPos: {
                        x: O.x,
                        y: minY
                },
                controllPos: [{
                        x: minX - (MAXX / 2 - maxX / 2),
                        y: O.y - height * 0.75
                },
                {
                        x: O.x,
                        y: MINY
                },
                ]
        }, { // 4
                startPos: {
                        x: O.x,
                        y: minY
                },
                endPos: {
                        x: maxX,
                        y: O.y - height / 4
                },
                controllPos: [{
                        x: O.x,
                        y: MINY
                },
                {
                        // x: maxX, y: MINY
                        x: maxX + (MAXX / 2 - maxX / 2),
                        y: O.y - height * 0.75
                },
                ]
        }, { // 5
                startPos: {
                        x: maxX,
                        y: O.y - height / 4
                },
                endPos: {
                        x: maxX,
                        y: O.y + height / 4
                },
                controllPos: [{
                        x: MAXX,
                        y: O.y - height / 2.2
                },
                {
                        x: MAXX,
                        y: O.y + height / 2.2
                },
                ]
        }]

        var updateArc = function (arcshape, arcData) {
                var str = "M" + arcData.startPos.x + " " + arcData.startPos.y + " ";
                str += "C " + arcData.controllPos[0].x + " " + arcData.controllPos[0].y + ", "; // 长短半径
                str += arcData.controllPos[1].x + " " + arcData.controllPos[1].y + ", "; // 长短半径
                str += arcData.endPos.x + " " + arcData.endPos.y + " ";

                arcshape
                        .attr("d", str);
                return arcshape;
        }

        for (var i = 0; i < _self.arcCDatas.length; i++) {
                var temparc = null;
                if (_self.arcShapes[i] == null) {
                        temparc = _self.contentGroup.append("path") // 标记 shape
                        _self.arcShapes[i] = temparc;
                } else
                        temparc = _self.arcShapes[i];
                updateArc(temparc, _self.arcCDatas[i]);


                var temparcbottom = null;
                if (_self.arcShapesBottom[i] == null) {
                        temparcbottom = _self.contentGroupBottom.append("path") // 标记 shape
                        _self.arcShapesBottom[i] = temparcbottom;
                } else
                        temparcbottom = _self.arcShapesBottom[i];
                updateArc(temparcbottom, _self.arcCDatas[i]);
        }

        if (_self.polyShape == null) {
                _self.polyShape = _self.contentGroup.append("path") // 标记 shape
        }

        if (_self.polyShapeBottom == null) {
                _self.polyShapeBottom = _self.contentGroupBottom.append("path") // 标记 shape
        }

        _self.polyShape
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.arcCDatas.length; i++) {
                                var temppos = _self.arcCDatas[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.startPos.x + " " + temppos.startPos.y;
                        }

                        if (_self.typeId == "3")
                                re += " Z";
                        return re;
                });

        _self.polyShapeBottom
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.arcCDatas.length; i++) {
                                var temppos = _self.arcCDatas[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.startPos.x + " " + temppos.startPos.y;
                        }

                        if (_self.typeId == "3")
                                re += " Z";
                        return re;
                });

        this.apandArcBaseInfo();
};

MarkupCloudDraw.prototype.apandArcBaseInfo = function () {
        var nRGBLColor = this.originData.selectedLineColor; // 线色
        var nRGBFillColor = this.originData.selectedFillColor; // 填充颜色
        var sFillType = this.originData.selectedFillType; // 填充类型 1 填充 2 填充  置于底层
        var sLineStyle = this.originData.selectedLineType; // 线型
        var wLineThick = this.originData.selectedLineWidth; // 线宽

        for (var i = 0; i < 6; i++) {
                var tempArc = this.arcShapes[i];
                var tempArcBottom = this.arcShapesBottom[i];

                if (tempArc == null)
                        continue;

                if (nRGBLColor) {
                        tempArc.attr("stroke", nRGBLColor);
                }

                if (wLineThick) {
                        tempArc.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
                }

                // fill   sFillType == 0 ? "#00000000" :
                var fillcolor = nRGBFillColor;
                tempArc.attr("fill", sFillType == 1 ? fillcolor : "#00000000");
                tempArcBottom.attr("fill", sFillType == 2 ? fillcolor : "#00000000");
                if (sLineStyle != 0) {
                        tempArc.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
                }
        }
        var fillcolor = nRGBFillColor;
        this.polyShape.attr("fill", sFillType == 1 ? fillcolor : "#00000000");
        this.polyShapeBottom.attr("fill", sFillType == 2 ? fillcolor : "#00000000");
        this.polyShapeBottom.attr("stroke-width", 0);
}
MarkupCloudDraw.prototype.setSelected = MarkupBase.prototype.setSelected

/**
 * 包围盒及黑点绘制 
 */
MarkupCloudDraw.prototype.addBoundBoxContents = MarkupBase.prototype.addBoundBoxContents

MarkupCloudDraw.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        var dotInfo = this.boundboxDots[index];
        var minX = d3.min(this.originData.pointList, function (d) {
                return d.x;
        }),
                minY = d3.min(this.originData.pointList, function (d) {
                        return d.y;
                }),
                maxX = d3.max(this.originData.pointList, function (d) {
                        return d.x;
                }),
                maxY = d3.max(this.originData.pointList, function (d) {
                        return d.y;
                });

        var widthO = Math.abs(maxX - minX);
        var heightO = Math.abs(maxY - minY);
        var widthN = 1;
        var heightN = 1;
        var minXN = 1;
        var minYN = 1;
        var maxXN = 1;
        var maxYN = 1;

        /**
         * box 0 左下  中下  右下  左中 （中中） 右中 左上 中上 右上
         */
        if (dotInfo.optType == 0) {
                if (mouseosY > maxY - 10 || mouseosX > maxX - 10)
                        return;
                minXN = mouseosX;
                minYN = mouseosY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 1) {
                if (mouseosY > maxY - 10)
                        return;

                minXN = minX;
                minYN = mouseosY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 2) {
                if (mouseosY > maxY - 10 || mouseosX < minX + 10)
                        return;

                minXN = minX;
                minYN = mouseosY;
                maxXN = mouseosX;
                maxYN = maxY;
        } else if (dotInfo.optType == 3) {
                if (mouseosX > maxX - 10)
                        return;

                minXN = mouseosX;
                minYN = minY;
                maxXN = maxX;
                maxYN = maxY;
        } else if (dotInfo.optType == 4) {
                if (mouseosX < minX + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = mouseosX;
                maxYN = maxY;
        } else if (dotInfo.optType == 5) {
                if (mouseosX > maxX - 10 || mouseosY < minY + 10)
                        return;

                minXN = mouseosX;
                minYN = minY;
                maxXN = maxX;
                maxYN = mouseosY;
        } else if (dotInfo.optType == 6) {
                if (mouseosY < minY + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = maxX;
                maxYN = mouseosY;
        } else if (dotInfo.optType == 7) {
                if (mouseosX < minX + 10 || mouseosY < minY + 10)
                        return;

                minXN = minX;
                minYN = minY;
                maxXN = mouseosX;
                maxYN = mouseosY;
        }
        widthN = maxXN - minXN;
        heightN = maxYN - minYN;

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempPoint = this.originData.pointList[i];
                var xN = (((tempPoint.x - minX) / widthO) * widthN) + minXN;
                var yN = (((tempPoint.y - minY) / heightO) * heightN) + minYN;

                tempPoint.x = xN;
                tempPoint.y = yN;
        }
        this.addContents();
        this.addBoundBoxContents();
};
///////////////////////////////////////////////////
/**
 * Markup draw a Arrow Polyline And Text
 * @param {*} originData 
 * type 11 
 */
function MarkupPolylineAndText(originData, inTypeId) {
        this.typeName = 'MarkupPolylineAndText';
        this._polylineShap = null;
        this._arrowLine = null;
        this._textShap = null;
        MarkupBase.call(this, originData, inTypeId);
}

MarkupPolylineAndText.prototype.addContents = function () {
        var _self = this;
        if (this._polylineShap == null)
                this._polylineShap = this.contentGroup.append("path"); // 标记 shape

        this._polylineShap
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.originData.pointList.length; i++) {
                                var temppos = _self.originData.pointList[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.x + " " + temppos.y;
                        }
                        return re;
                });

        // arrow
        if (this._arrowLine == null)
                this._arrowLine = this.contentGroup.append("path"); // 标记 shape

        var baseVector = {
                x: _self.originData.pointList[1].x - _self.originData.pointList[0].x,
                y: _self.originData.pointList[1].y - _self.originData.pointList[0].y
        };

        var baseNormalVector = {
                x: _self.originData.pointList[1].y - _self.originData.pointList[0].y,
                y: _self.originData.pointList[0].x - _self.originData.pointList[1].x
        };

        var arrowCenterPointInLine = movePointByVector(baseVector, _self.originData.pointList[0], 3);
        var arrowDot0 = movePointByVector(baseNormalVector, arrowCenterPointInLine, 1);
        var arrowDot1 = movePointByVector(baseNormalVector, arrowCenterPointInLine, -1);

        this._arrowLine
                .attr("d", function () {
                        var re = "M";
                        re += arrowDot0.x + " " + arrowDot0.y;
                        re += " L ";
                        re += _self.originData.pointList[0].x + " " + _self.originData.pointList[0].y;
                        re += " L ";
                        re += arrowDot1.x + " " + arrowDot1.y;
                        return re;
                });
        // arrow


        // text
        var _textPoint = this.originData.pointList[this.originData.pointList.length - 1]; // 点1
        if (this._textShap == null)
                this._textShap = this.contentGroup.append("text") // 标记 shape

        var lastFontSize = this._textShap.attr("font-size");
        var lastFontStr = this._textShap.attr("lastTest");

        this._textShap
                // .text(this.originData.text)
                .attr("x", function () {
                        return 0;
                })
                .attr("y", function () {
                        return 0;
                })
                .attr("fill", this.originData.selectedLineColor)
                .attr("font-size", this.originData.selectedFontSize * g_markupTextDefaultWidth)
                .attr("lengthAdjust", "spacingAndGlyphs") // spacing  空间平均分配到文字间
                .attr("dominant-baseline", "ideographic") // 调整文字的基线
                .attr("text-decoration", this.originData.selectedUnderline ? "underline" : "none") // "underline")
                .attr("font-style", this.originData.selectedItalics ? "italic" : "normal")
                .attr("font-weight", this.originData.selectedBold ? "bold" : "normal")
                .attr("font-family", this.originData.selectedFont);

        if (lastFontStr != this.originData.text ||
                lastFontSize != this.originData.selectedFontSize * g_markupTextDefaultWidth) {

                this._textShap.selectAll("tspan").each(function () {
                        d3.select(this).remove();
                })

                var temptext = this.originData.text;
                var texttips = temptext.split("\n");

                for (var i = 0; i < texttips.length; i++) {
                        // re_str += "<tspan>" + texttips[i] + "</tspan>";
                        this._textShap.append("tspan").text(texttips[i])
                                .attr('x', 0)
                                .attr('y', (i) * this.originData.selectedFontSize * g_markupTextDefaultWidth);
                }

                this._textShap.attr("lastTest", this.originData.text)
        }

        // var temptext = this.originData.text;
        // var texttips = temptext.split("\n");

        // for (var i = 0; i < texttips.length; i++) {
        //   // re_str += "<tspan>" + texttips[i] + "</tspan>";
        //   this._textShap.append("tspan").text(texttips[i])
        //     .attr('x', 0)
        //     .attr('y', 0 + (i + 0.3) * this.originData.selectedFontSize * 0.5 * g_markupLineWidth * 10);
        // }

        this._textShap.attr("transform", function () {
                var scalex = 1;
                var scaley = -1;
                var str = '';
                str += "scale(" + scalex + "," + scaley + ") ";
                str += "translate(" + _textPoint.x + "," + (0 - _textPoint.y + _self.originData.selectedFontSize * 1.1) + ")";

                return str;
        })
        // text

        this.apandBaseInfoExt();
};

/**
 * 包围盒及黑顶绘制 
 */
MarkupPolylineAndText.prototype.addBoundBoxContents = function () {
        var _MarkupBaseSelf = this;
        var strokeWidth = 0;
        var blockWidth = g_editDotWidth;

        var dotpointsList = genNormalBoundingDotPositions(
                this.originData.pointList,
                blockWidth,
                strokeWidth
        )

        var minX = dotpointsList.minX;
        var minY = dotpointsList.minY;
        var width = dotpointsList.width;
        var height = dotpointsList.height;

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
        }

        this.boundBoxShap
                .attr("x", minX - blockWidth - strokeWidth)
                .attr("y", minY - blockWidth - strokeWidth)
                .attr("width", width + blockWidth * 2 + strokeWidth * 2)
                .attr("height", height + blockWidth * 2 + strokeWidth * 2)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000033")
                .attr("stroke-opacity", "0")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);

        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("dblclick", function () {
                g_openTextInputFun(_MarkupBaseSelf.originData.text);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        })

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempDotInfo = this.originData.pointList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        dotInfoLeftBottom.optType = i;

                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.on("mouseup", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseUp(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.attr("style", "cursor:ne-resize");

                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x - g_editDotWidth / 2)
                        .attr("y", tempDotInfo.y - g_editDotWidth / 2)
                        .attr("width", g_editDotWidth)
                        .attr("height", g_editDotWidth)
                        .attr("stroke", g_editDotStroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", g_editDotFill);
        }
};
MarkupPolylineAndText.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupPolylineAndText.prototype.apandBaseInfoExt = function () {
        var nRGBLColor = this.originData.selectedLineColor; // 线色
        var sLineStyle = this.originData.selectedLineType; // 线型
        var wLineThick = this.originData.selectedLineWidth; // 线宽

        if (nRGBLColor) {
                this._polylineShap.attr("stroke", nRGBLColor);
                this._arrowLine.attr("stroke", nRGBLColor);

        }

        if (wLineThick) {
                this._polylineShap.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
                this._arrowLine.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
        }

        if (sLineStyle != 0) {
                this._polylineShap.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
                this._arrowLine.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
        }

        this._polylineShap.attr("fill", "#00000000");
        this._arrowLine.attr("fill", "#00000000");
}

MarkupPolylineAndText.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        if (index < this.originData.pointList.length) {
                this.originData.pointList[index].x = mouseosX;
                this.originData.pointList[index].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * 球标 13 - 16
 */
function MarkupBallMarker(originData, inTypeId) {
        this.typeName = 'MarkupBallMarker';
        this._polylineShap = null;
        this._textShap = null;
        this._ballShap = null;
        this._ballShapBottom = null;
        MarkupBase.call(this, originData, inTypeId);
}

MarkupBallMarker.prototype.addContents = function () {
        var _self = this;
        // if (_self.originData.pointList.length == 1) {
        //   _self.originData.pointList.push({
        //     x: _self.originData.pointList[0].x,
        //     y: _self.originData.pointList[0].y
        //   });
        // }

        if (this._polylineShap == null) {
                this._polylineShap = this.contentGroup.append("path"); // 标记 shape
                this._polylineShap.attr("id", "ball_polyline");
        }

        this._polylineShap
                .attr("d", function () {
                        var re = "M";
                        for (var i = 0; i < _self.originData.pointList.length; i++) {
                                var temppos = _self.originData.pointList[i];
                                if (i != 0)
                                        re += " L ";
                                re += temppos.x + " " + temppos.y;
                        }
                        return re;
                });

        if (this._textShap == null) {
                this._textShap = this.contentGroup.append("text"); // 标记 shape
        }

        this._textShap
                .text(this.originData.text)
                // .text("-1")
                .attr("x", function () {
                        return 0;
                })
                .attr("y", function () {
                        return 0;
                })
                .attr("fill", this.originData.selectedLineColor)
                .attr("font-size", this.originData.selectedFontSize * g_markupTextDefaultWidth)
                .attr("lengthAdjust", "spacingAndGlyphs") // spacing  空间平均分配到文字间
                .attr("dominant-baseline", "ideographic") // 调整文字的基线
                .attr("text-decoration", this.originData.selectedUnderline ? "underline" : "none") // "underline")
                .attr("font-style", this.originData.selectedItalics ? "italic" : "normal")
                .attr("font-weight", this.originData.selectedBold ? "bold" : "normal")
                .attr("font-family", this.originData.selectedFont);

        if (this._ballShap != null) {
                var lastPos1 = _self.originData.pointList[_self.originData.pointList.length - 1];
                var lastPos0 = _self.originData.pointList[_self.originData.pointList.length - 2];
                var baseVector = {
                        x: lastPos1.x - lastPos0.x,
                        y: lastPos1.y - lastPos0.y
                };

                if (this._textShap != null) {

                        var box1 = this._textShap._groups;
                        var box11 = box1[0][0];
                        var boxx = box11.getBBox();

                        // let maxEdge = Math.min(boxx.width, boxx.height);
                        let maxEdge = boxx.height * 1;

                        var shapeRadius = maxEdge * 0.8;
                        var centerPos = movePointByVector(baseVector, lastPos1, shapeRadius);


                        this._textShap.attr("transform", function () {
                                var scalex = 1;
                                var scaley = -1;
                                var str = '';
                                str += "scale(" + scalex + "," + scaley + ") ";
                                str += "translate(" + (Number(centerPos.x) - boxx.width / 2) + "," + (0 - Number(centerPos.y) + boxx.height / 2) + ")";

                                return str;
                        })
                }


                if (this.typeId == 13) {
                        this._ballShap.attr("cx", function () {
                                return centerPos.x;
                        })
                                .attr("cy", function () {
                                        return centerPos.y;
                                })
                                .attr("rx", function () {
                                        return shapeRadius;
                                })
                                .attr("ry", function () {
                                        return shapeRadius;
                                });

                        this._ballShapBottom.attr("cx", function () {
                                return centerPos.x;
                        })
                                .attr("cy", function () {
                                        return centerPos.y;
                                })
                                .attr("rx", function () {
                                        return shapeRadius;
                                })
                                .attr("ry", function () {
                                        return shapeRadius;
                                });
                } else if (this.typeId == 14) {
                        this._ballShap.attr("x", function () {
                                return centerPos.x - shapeRadius;
                        })
                                .attr("y", function () {
                                        return centerPos.y - shapeRadius
                                })
                                .attr("width", function () {
                                        return shapeRadius * 2
                                })
                                .attr("height", function () {
                                        return shapeRadius * 2
                                });

                        this._ballShapBottom.attr("x", function () {
                                return centerPos.x - shapeRadius;
                        })
                                .attr("y", function () {
                                        return centerPos.y - shapeRadius
                                })
                                .attr("width", function () {
                                        return shapeRadius * 2
                                })
                                .attr("height", function () {
                                        return shapeRadius * 2
                                });
                } else if (this.typeId == 15) {
                        this._ballShap.attr("d", function () {
                                var re = "M ";
                                re += centerPos.x + " " + (centerPos.y + shapeRadius * 1.2);
                                re += " L ";
                                re += (centerPos.x - shapeRadius / 0.8) + " " + (centerPos.y - shapeRadius / 1.2);
                                re += " L ";
                                re += (centerPos.x + shapeRadius / 0.8) + " " + (centerPos.y - shapeRadius / 1.2);
                                re += " Z";
                                return re;

                        });

                        this._ballShapBottom.attr("d", function () {
                                var re = "M ";
                                re += centerPos.x + " " + (centerPos.y + shapeRadius * 1.2);
                                re += " L ";
                                re += (centerPos.x - shapeRadius / 0.8) + " " + (centerPos.y - shapeRadius / 1.2);
                                re += " L ";
                                re += (centerPos.x + shapeRadius / 0.8) + " " + (centerPos.y - shapeRadius / 1.2);
                                re += " Z";
                                return re;

                        });
                } else if (this.typeId == 16) {
                        this._ballShap.attr("d", function () {
                                var re = "M ";
                                re += (centerPos.x - shapeRadius) + " " + centerPos.y;
                                re += " L ";
                                re += (centerPos.x) + " " + (centerPos.y + shapeRadius);
                                re += " L ";
                                re += (centerPos.x + shapeRadius) + " " + (centerPos.y);
                                re += " L ";
                                re += (centerPos.x) + " " + (centerPos.y - shapeRadius);
                                re += " Z";
                                return re;

                        });

                        this._ballShapBottom.attr("d", function () {
                                var re = "M ";
                                re += (centerPos.x - shapeRadius) + " " + centerPos.y;
                                re += " L ";
                                re += (centerPos.x) + " " + (centerPos.y + shapeRadius);
                                re += " L ";
                                re += (centerPos.x + shapeRadius) + " " + (centerPos.y);
                                re += " L ";
                                re += (centerPos.x) + " " + (centerPos.y - shapeRadius);
                                re += " Z";
                                return re;

                        });
                }
        }

        this.apandBaseInfoExt();
};

MarkupBallMarker.prototype.apandBaseInfoExt = function () {
        var nRGBLColor = this.originData.selectedLineColor; // 线色
        var sLineStyle = this.originData.selectedLineType; // 线型
        var wLineThick = this.originData.selectedLineWidth; // 线宽
        var nRGBFillColor = this.originData.selectedFillColor; // 填充颜色
        var sFillType = this.originData.selectedFillType; // 填充类型 1 填充 2 填充  置于底层

        if (nRGBLColor) {
                if (this.isSelected)
                        this._polylineShap.attr("stroke", g_ballMarkerSelectColor);
                else
                        this._polylineShap.attr("stroke", nRGBLColor);
                if (this._ballShap != null) {
                        if (this.isSelected)
                                this._ballShap.attr("stroke", g_ballMarkerSelectColor);
                        else
                                this._ballShap.attr("stroke", nRGBLColor);
                }
        }

        if (wLineThick) {
                this._polylineShap.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
                if (this._ballShap)
                        this._ballShap.attr("stroke-width", g_markupLineWidth * wLineThick / 2);
        }

        if (sLineStyle != 0) {
                this._polylineShap.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
                if (this._ballShap)
                        this._ballShap.attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[sLineStyle]);
        }

        this._polylineShap.attr("fill", "#000000");
        this._polylineShap.attr("fill-opacity", "0.0");

        if (this._ballShap != null) {
                var fillcolor = nRGBFillColor;
                this._ballShap.attr("fill", sFillType == 1 ? fillcolor : "#00000000");
                this._ballShapBottom.attr("fill", sFillType == 2 ? fillcolor : "#00000000");
        }

        // if(this.originData.typeId >= 13 && this.originData.typeId <= 16) {
        //   this._polylineShap.attr("stroke", "#ff0000");
        //   if (this._ballShap != null)
        //     this._ballShap.attr("stroke", "#ff0000");
        // }

}

/**
 * 包围盒及黑顶绘制 
 */
MarkupBallMarker.prototype.addBoundBoxContents = function () {
        var _MarkupBaseSelf = this;
        var strokeWidth = 0;
        var blockWidth = g_editDotWidth;

        var dotpointsList = genNormalBoundingDotPositions(
                this.originData.pointList,
                blockWidth,
                strokeWidth
        )

        var minX = dotpointsList.minX;
        var minY = dotpointsList.minY;
        var width = dotpointsList.width;
        var height = dotpointsList.height;

        if (this.boundBoxShap == null) {
                this.boundBoxShap = this.boundboxGroup.append("rect");
                this.boundBoxShap.attr("style", "cursor: move;");
        }

        this.boundBoxShap
                .attr("x", minX - blockWidth - strokeWidth)
                .attr("y", minY - blockWidth - strokeWidth)
                .attr("width", width + blockWidth * 2 + strokeWidth * 2)
                .attr("height", height + blockWidth * 2 + strokeWidth * 2)
                .attr("stroke-dasharray", LINE_STROKE_DASH_TYPE[2])
                .attr("stroke", "#00000033")
                .attr("stroke-opacity", "0")
                .attr("fill", "#00000000")
                .attr("stroke-width", g_markupLineWidth * 2 / 2);

        this.boundBoxShap.on("mousedown", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseDown(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为
        });

        this.boundBoxShap.on("mouseup", function () {
                var dataindex = d3.select(this).attr("dataIndex");
                _MarkupBaseSelf.onBoundBoxShapeMouseUp(dataindex);
                event.stopPropagation(); //阻止事件冒泡
                event.preventDefault(); //阻止默认行为

                if (d3.event.button != 0) {
                        g_doRightClick = false;
                }
        });

        for (var i = 0; i < this.originData.pointList.length; i++) {
                var tempDotInfo = this.originData.pointList[i];
                var dotInfoLeftBottom = {}; // data & shape

                var tempDotShape = null;
                // 初次创建
                if (_MarkupBaseSelf.boundboxDots.length >= i + 1 && _MarkupBaseSelf.boundboxDots[i] != null) {
                        tempDotShape = _MarkupBaseSelf.boundboxDots[i].dotShap;
                } else {
                        // 更改形状
                        tempDotShape = this.boundboxGroup.append("rect");
                        dotInfoLeftBottom.dotShap = tempDotShape;
                        _MarkupBaseSelf.boundboxDots.push(dotInfoLeftBottom);

                        tempDotShape.dataIndex = i;
                        dotInfoLeftBottom.optType = i;


                        // 点击黑点 
                        tempDotShape.on("mousedown", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseDown(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.on("mouseup", function () {
                                var dataindex = d3.select(this).attr("dataIndex");
                                _MarkupBaseSelf.onBoundBoxDotMouseUp(dataindex);
                                event.stopPropagation(); //阻止事件冒泡
                                event.preventDefault(); //阻止默认行为
                        });

                        tempDotShape.attr("style", "cursor:ne-resize");
                        this.boundboxGroup.attr("visibility", "hidden");
                }

                // 修改形状
                tempDotShape
                        .attr("x", tempDotInfo.x - g_editDotWidth / 2)
                        .attr("y", tempDotInfo.y - g_editDotWidth / 2)
                        .attr("width", g_editDotWidth)
                        .attr("height", g_editDotWidth)
                        .attr("stroke", g_editDotStroke)
                        .attr("stroke-width", "0.07")
                        .attr("dataIndex", i)
                        .attr("fill", g_editDotFill);
        }
};
MarkupBallMarker.prototype.setSelected = MarkupBase.prototype.setSelected

MarkupBallMarker.prototype.doAtAddEnd = function () {
        if (this.typeId == 13) {
                this._ballShap = this.contentGroup.insert("ellipse", "#ball_polyline");
                this._ballShapBottom = this.contentGroupBottom.append("ellipse");
        } else if (this.typeId == 14) {
                this._ballShap = this.contentGroup.insert("rect", "#ball_polyline");
                this._ballShapBottom = this.contentGroupBottom.append("rect");
        } else if (this.typeId == 15 || this.typeId == 16) {
                this._ballShap = this.contentGroup.insert("path", "#ball_polyline"); // 标记 shape
                this._ballShapBottom = this.contentGroupBottom.append("path");
        }
}

MarkupBallMarker.prototype.updateDrawShape = function (index, mouseosX, mouseosY) {
        if (index < this.originData.pointList.length) {
                this.originData.pointList[index].x = mouseosX;
                this.originData.pointList[index].y = mouseosY;
                this.addContents();
                this.addBoundBoxContents();
        }
};

/**
 * Markup draw a Line
 * @param {*} originData 
 * type  17 line group
 */
function LineGroup(originData, inTypeId) {
        console.log(originData, "SSSSSSSSSSSSSSSSSSs")
        if (originData.groupItems.length == 0) {
                return
        }
        let temp = {
                fontWidth: '10',
                selectedBold: false,
                selectedFillType: 0,
                selectedFont: 'Meiryo',
                selectedFontSize: '10',
                selectedItalics: false,
                selectedLineColor: 'blue',
                selectedLineType: 0,
                selectedLineWidth: 10,
                selectedUnderline: false,
                defaultLineColor: 'blue',
                text: '',
                prlNo: 1,
                pointList: []
        }


        let tempPrlNo = -1;

        // originData.groupItems.forEach((i, v) => {
        //         if (tempPrlNo != i.dtlNo) {
        //                 if (v != 0 && originData.groupItems[v-1].shapeType == 'line') {
        //                         temp.fEntType = 2;
        //                         temp.shapeType = 2;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupLine(temp, 2)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }
        //                 if (v != 0 && originData.groupItems[v-1].shapeType == 'closeline') {
        //                         temp.fEntType = 3;
        //                         temp.shapeType = 3;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupLine(temp, 3)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }
        //                 if (v != 0 && originData.groupItems[v-1].shapeType == 'rect') {
        //                         temp.fEntType = 4;
        //                         temp.shapeType = 4;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupRect(temp, 4)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }

        //                 temp.pointList.push(
        //                         {
        //                                 x: i.points[0].x,
        //                                 y: i.points[0].y,
        //                         },
        //                         {
        //                                 x: i.points[1].x,
        //                                 y: i.points[1].y,
        //                         }
        //                 )
        //                 tempPrlNo = i.dtlNo
        //         } else {
        //                 temp.pointList.push(
        //                         {
        //                                 x: i.points[1].x,
        //                                 y: i.points[1].y,
        //                         }
        //                 )
        //         }

        //         if (v == originData.groupItems.length - 1 && temp.pointList.length != 0) {
        //                 if (originData.groupItems[v].shapeType == 'line') {
        //                         temp.fEntType = 2;
        //                         temp.shapeType = 2;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupLine(temp, 2)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }
        //                 if (originData.groupItems[v].shapeType == 'closeline') {
        //                         temp.fEntType = 3;
        //                         temp.shapeType = 3;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupLine(temp, 3)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }
        //                 if (originData.groupItems[v].shapeType == 'rect') {
        //                         temp.fEntType = 4;
        //                         temp.shapeType = 4;
        //                         temp.prlNo = originData.prlNo;
        //                         this._shape = new MarkupRect(temp, 4)
        //                         g_markupList.push(this._shape);

        //                         temp.pointList = [];
        //                 }

        //         }
        // })
        // debugger
        //处理矩形
        if (originData.groupItems[0].shapeType == 'rect') {
                console.log('originData.prlNo', originData.prlNo);

                temp.fEntType = 4;
                temp.shapeType = 4;
                temp.prlNo = originData.prlNo;
                temp.pointList = [
                        {
                                x: originData.groupItems[0].points[0].x,
                                y: originData.groupItems[0].points[0].y,
                        },
                        {
                                x: originData.groupItems[0].points[1].x,
                                y: originData.groupItems[0].points[1].y,
                        }
                ]
                this._shape = new MarkupRect(temp, 4)
                g_markupList.push(this._shape);
        } else if (originData.groupItems[0].shapeType == 'closeline') {
                temp.fEntType = 3;
                temp.shapeType = 3;
                temp.prlNo = originData.prlNo;
                temp.pointList = [];
                let tempPrlNo = -1;
                console.log('fsdfsdf', temp);


                originData.groupItems.forEach((i, v) => {

                        // debugger

                        console.log(temp, originData)

                        if (tempPrlNo != i.dtlNo) {
                                if (temp.pointList.length != 0) {
                                        this._shape = new MarkupLine(temp, 3)
                                        g_markupList.push(this._shape);

                                        temp.pointList = [];
                                }
                                temp.pointList.push(
                                        {
                                                x: i.points[0].x,
                                                y: i.points[0].y,
                                        },
                                        {
                                                x: i.points[1].x,
                                                y: i.points[1].y,
                                        }
                                )
                                tempPrlNo = i.dtlNo
                        } else {
                                temp.pointList.push(
                                        {
                                                x: i.points[1].x,
                                                y: i.points[1].y,
                                        }
                                )
                        }

                        if (v == originData.groupItems.length - 1 && temp.pointList.length != 0) {
                                this._shape = new MarkupLine(temp, 3)
                                g_markupList.push(this._shape);

                        }
                })
        } else if (originData.groupItems[0].shapeType == 'line') {
                temp.fEntType = 2;
                temp.shapeType = 2;
                temp.prlNo = originData.prlNo;
                temp.pointList = []
                let tempPrlNo = -1;

                originData.groupItems.forEach((i, v) => {


                        if (tempPrlNo != i.dtlNo) {
                                if (temp.pointList.length != 0) {
                                        this._shape = new MarkupLine(temp, 2)
                                        g_markupList.push(this._shape);

                                        temp.pointList = [];
                                }
                                temp.pointList.push(
                                        {
                                                x: i.points[0].x,
                                                y: i.points[0].y,
                                        },
                                        {
                                                x: i.points[1].x,
                                                y: i.points[1].y,
                                        }
                                )
                                tempPrlNo = i.dtlNo
                        } else {
                                temp.pointList.push(
                                        {
                                                x: i.points[1].x,
                                                y: i.points[1].y,
                                        }
                                )
                        }

                        if (v == originData.groupItems.length - 1 && temp.pointList.length != 0) {
                                this._shape = new MarkupLine(temp, 2)
                                g_markupList.push(this._shape);

                        }
                })
        }
}


/**
 * 设置选中ui和状态
 * @param {*} isS 
 * @param {*} shouldCallBack 
 */
LineGroup.prototype.setSelected = function (isS, shouldCallBack = true) {
        g_SelectedMarkup = this;
        this.isSelected = isS;

        if (this.isSelected)
                this.contentGroup.attr("stroke", "#ff0000aa");
        else
                this.contentGroup.attr("stroke", this.originData.defaultLineColor);

        if (isS && g_selectedCallBackFun && shouldCallBack)
                g_selectedCallBackFun(g_SelectedMarkup.originData);
};

function testAddLineGroupsByParams(inParams) {
        console.log(inParams, "PPPPPPPPPPPPPPP")


        for (let i = 0; i < inParams.length; i++) {
                let tempParams = inParams[i];

                let shapData = {
                        defaultLineColor: "#0000ff",
                        defaultLineWidth: '10',
                        fEntType: '17',
                        groupItems: [],
                        prlNo: tempParams.prlNo,
                        sId: tempParams.sId,
                }

                let testParamsShaps;
                let tempDtlNo = inParams[i].groupItems[0].dtlNo;
                tempParams.groupItems.forEach((item, index) => {
                        if (item.dtlNo == tempDtlNo) {
                                shapData.groupItems.push(item)
                                console.log(11111, inParams)
                        } else {
                                testParamsShaps = new LineGroup(shapData, shapData.fEntType);
                                tempDtlNo = item.dtlNo;
                                shapData.groupItems = [];
                                shapData.groupItems.push(item)
                                console.log(22222, inParams)
                        }
                        if (index == tempParams.groupItems.length - 1) {
                                // shapData.groupItems.push(item)

                                testParamsShaps = new LineGroup(shapData, shapData.fEntType);
                                shapData.groupItems = [];
                                console.log(33333, inParams)
                        }
                })
        }
}

/**
 * 根据传入的参数值创建markup
 * @param {*} shapeTypeId shape类型
 * @param {*} params 参数
 * @param {*} inPos 传入位置
 */
function addMarkUpByParams(shapeTypeId, params, inPos) {
        var markupData = {};
        var mouseosX = GetMousePositonOnSvgX();
        var mouseosY = GetMousePositonOnSvgY();

        markupData.pointList = [];
        markupData.pointList.push({
                x: mouseosX,
                y: mouseosY
        });
        markupData.pointList.push({
                x: mouseosX,
                y: mouseosY
        });

        markupData.shapeType = shapeTypeId;
        markupData.fEntType = shapeTypeId;
        markupData.selectedFont = params.selectedFont;
        markupData.selectedFontSize = params.selectedFontSize;
        markupData.fontWidth = params.fontWidth;
        markupData.selectedBold = params.selectedBold;
        markupData.selectedItalics = params.selectedItalics;
        markupData.selectedUnderline = params.selectedUnderline;
        markupData.selectedLineType = params.selectedLineType;
        markupData.selectedLineWidth = params.selectedLineWidth;
        markupData.selectedLineColor = params.selectedLineColor;
        markupData.selectedFillColor = params.selectedFillColor;
        markupData.selectedFillType = params.selectedFillType;
        markupData.text = "";

        if (g_layerActiveId != -1)
                markupData.sLayId = g_layerActiveId;

        var testShape = null;
        if (shapeTypeId == 1) {
                markupData.selectedFillType = 0;
                testShape = new MarkupLine(markupData, shapeTypeId);
        } else if (shapeTypeId == 2) {
                markupData.selectedFillType = 0;
                testShape = new MarkupLine(markupData, shapeTypeId);
        } else if (shapeTypeId == 3) {
                if (markupData.selectedFillType == 0)
                        markupData.selectedFillType = 1;
                testShape = new MarkupLine(markupData, shapeTypeId);
        } else if (shapeTypeId == 4) {
                markupData.selectedFillType = 0;
                testShape = new MarkupRect(markupData, shapeTypeId);
        } else if (shapeTypeId == 12) {
                markupData.selectedFillColor = markupData.selectedLineColor;
                markupData.selectedFillType = 2;
                testShape = new MarkupRect(markupData, shapeTypeId);
        } else if (shapeTypeId == 5) {
                if (markupData.selectedFillType == 0)
                        markupData.selectedFillType = 1;
                testShape = new MarkupRect(markupData, shapeTypeId);
        } else if (shapeTypeId == 6) {
                markupData.selectedFillType = 0;
                testShape = new MarkupEllipse(markupData, shapeTypeId);
        } else if (shapeTypeId == 7) {
                markupData.selectedFillType = 0;
                testShape = new MarkupArc(markupData, shapeTypeId);
        } else if (shapeTypeId == 8) {
                markupData.selectedFillType = 0;
                testShape = new MarkupHandDraw(markupData, shapeTypeId);
        } else if (shapeTypeId == 9) { // cloud
                markupData.selectedFillType = 0;
                testShape = new MarkupCloudDraw(markupData, shapeTypeId);
        } else if (shapeTypeId == 10) { // text
                markupData.selectedFillType = 0;
                testShape = new MarkupText(markupData, shapeTypeId);

                if (shapeTypeId == 10) { // text
                        if (g_openTextInputFun)
                                g_openTextInputFun("");
                        // return;
                }
        } else if (shapeTypeId == 11) { // text
                testShape = new MarkupPolylineAndText(markupData, shapeTypeId);
        } else if (shapeTypeId >= 13 && shapeTypeId <= 16) { // text
                markupData.text = "-1"
                testShape = new MarkupBallMarker(markupData, shapeTypeId);
        }

        g_markupList.push(testShape);
        return testShape;
}

/**
 * 鼠标点击 增加一个点数据
 * @param {*} shapeTypeId 
 * @param {*} params 
 * @param {*} inPos 
 */
function addMarkUpPosition(shapeTypeId, params, inPos) {
        var tempTypeId = g_SelectedMarkup.typeId;
        var posList = g_SelectedMarkup.originData.pointList;
        var posListLen = posList.length;

        var _isBackToAdd = false;

        if (tempTypeId == 1 || shapeTypeId == 4 || shapeTypeId == 5 ||
                shapeTypeId == 6 || shapeTypeId == 9 || shapeTypeId == 10 || shapeTypeId == 12) {
                if (posListLen < 2)
                        posList.push(inPos);
                else
                        _isBackToAdd = true;
        } else if (shapeTypeId == 2 || shapeTypeId == 3 || shapeTypeId == 11 ||
                (shapeTypeId >= 13 && shapeTypeId <= 16)) {
                posList.push(inPos);

        } else if (shapeTypeId == 7) {
                if (posListLen < 3)
                        posList.push(inPos);
        } else if (shapeTypeId == 8) {
                posList.push(inPos);
        }

        g_SelectedMarkup.addContents();
        g_SelectedMarkup.addBoundBoxContents();
        return _isBackToAdd;
}

function Del_g_SelectedMarkup(prlNo) {
        console.log(g_SelectedMarkup, g_markupList, "DDDDDDDDDDDDDDDDDdEEEEEEEEEEEEEEEEEEEE")
        console.log(g_markupList, "DDDDDDDDDDDDDDDDDdEEEEEEEEEEEEEEEEEEEE")

        g_SelectedMarkup.rootGroup.remove();
        g_SelectedMarkup.contentGroupBottom.remove();


        if (g_state == OPT_STATE.STATE_NORMAL) {
                if (g_SelectedMarkup != null && g_SelectedMarkup.isSelected) {

                        for (var i = 0; i < g_markupList.length; i++) {
                                var listItem = g_markupList[i];
                                if (listItem.originData.prlNo == prlNo) {
                                        g_markupList.splice(i, 1);
                                        i--;
                                        // listItem.rootGroup.remove();
                                        // listItem.contentGroupBottom.remove();
                                }
                        }
                        g_SelectedMarkup = null;
                }
        }
}

function tryDeleteSelectMarkup(prlNo) {
        console.log(g_SelectedMarkup, "DDDDDDDDDDDDDDDDDdEEEEEEEEEEEEEEEEEEEE")
        if ((g_state == OPT_STATE.STATE_NORMAL) || (g_state == OPT_STATE.STATE_ADDING)) {
                if (g_SelectedMarkup != null && g_SelectedMarkup.isSelected) {

                        for (var i = 0; i < g_markupList.length; i++) {
                                var listItem = g_markupList[i];
                                if (listItem == g_SelectedMarkup) {
                                                if ((listItem.originData.selectTableItemprlNo == prlNo)
                                                 || (listItem.originData.prlNo == prlNo)) {
                                                g_markupList.splice(i, 1);
                                                i--;
                                                listItem.rootGroup.remove();
                                                listItem.contentGroupBottom.remove();
                                        }
                                }
                        }



                        g_SelectedMarkup = null;
                }
        }
}

function tryDeleteMarkupByData(e) {
        for (var i = 0; i < g_markupList.length; i++) {
                var listItem = g_markupList[i];
                if (listItem == e) {
                        g_markupList.splice(i, 1);
                        break;
                }
        }

        e.rootGroup.remove();
        e.contentGroupBottom.remove();
        e = null;
}

function clearAllMarkups() {
        for (var i = 0; i < g_markupList.length; i++) {
                var listItem = g_markupList[i];
                listItem.rootGroup.remove();
                listItem.contentGroupBottom.remove();
                g_markupList.splice(i, 1);
                i--;
        }

        g_layerActiveId = -1;
        g_layerList = [];
}

function onInputDialogClose() {
        if (g_state == OPT_STATE.STATE_ADDING)
                changeGlobalState(3, g_createShapeTypeId);
}

/**
 * 点沿向量移动的一段距离后的点
 * @param {*} vectorIn 
 * @param {*} point 
 * @param {*} distance 
 */
var movePointByVector = (vectorIn, point, distance) => {
        var vectorMagnitude = Math.sqrt(Math.pow(vectorIn.x, 2) + Math.pow(vectorIn.y, 2))
        var re = point;
        if (vectorMagnitude != 0) {
                var unitVector = {};
                unitVector.x = vectorIn.x / vectorMagnitude;
                unitVector.y = vectorIn.y / vectorMagnitude;

                re = {
                        x: point.x + (unitVector.x * distance),
                        y: point.y + (unitVector.y * distance)
                };
        }
        return re;
}

function setUpdateMarkupBaseInfoCallback(fun) {
        g_updateMarkupBaseInfoFun = fun;
}

function setContextMenuDoubleClickFun(fun) {
        g_contextMenuDoubleClickFun = fun;
}

function setLeftMouseClickFun(fun) {
        g_leftMouseClickFun = fun;
}

function setOnAddMarkupDataFun(fun) {
        g_onAddMarkupDataFun = fun;
}


var getValueAndFliterDot = function (parentTag, tagName) {
        var typeList = parentTag.getElementsByTagName(tagName);
        if (typeList == null || typeList.length == 0)
                return "";

        var type = typeList[0].textContent;
        var typeNew = type.replace(/"/g, "");
        return typeNew;
};

var genValidColorStr = function (originColor) {
        var replaceed = originColor.replace("0x00", "");
        var bStr = replaceed.substring(0, 2);
        var gStr = replaceed.substring(2, 4);
        var rStr = replaceed.substring(4, 6);
        return '#' + rStr + gStr + bStr;
};

/**
 * 文件导入Markup数据
 * @param {*} path 
 */
function loadMarkupsFromFile(path) {
        // 创建一个新的xhr対象
        let xhr = null;
        if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
        } else {
                // IE
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        path += "?" + "dt=" + new Date().getTime();
        xhr.open("GET", path, false);
        xhr.overrideMimeType("text/html;charset=utf-8");
        // xhr.setRequestHeader("Cache-Control","no-cache");
        // xhr.header('Access-Control-Allow-Origin', '*');
        xhr.send(null);
        // console.log(xhr.responseText.replace(/\s*/g, ""));
        var xmlStr = xhr.responseText;
        var parser = new DOMParser();

        if (xmlStr == null) {
                return false;
        }

        clearAllMarkups();
        var xmlDoc = parser.parseFromString(xmlStr, "text/xml");

        // 提取baseinfo
        var lstField = xmlDoc.getElementsByTagName("lstField");
        var baseI = {};

        if (lstField && lstField.length > 0) {
                baseI.userName = getValueAndFliterDot(lstField[0], "UserName");
                baseI.departName = getValueAndFliterDot(lstField[0], "DepartName");
                baseI.companyName = getValueAndFliterDot(lstField[0], "CompanyName");
                baseI.address = getValueAndFliterDot(lstField[0], "Address");
                baseI.phoneNumber = getValueAndFliterDot(lstField[0], "PhoneNumber");
        }

        // <dpOffsets x="19.694813" y="103.314619" z="0.000000"></dpOffsets>
        // 获取markup文件中的位置偏移参数，绘制markup时候计算偏移
        var dpOffsetsElement = xmlDoc.getElementsByTagName("dpOffsets");
        if (dpOffsetsElement && dpOffsetsElement.length > 0) {
                var x = dpOffsetsElement[0].getAttribute("x");
                var y = dpOffsetsElement[0].getAttribute("y");
                g_positionDeviation.x = x;
                g_positionDeviation.y = y;
        } else {
                g_positionDeviation.x = 0;
                g_positionDeviation.y = 0;
        }

        if (g_updateMarkupBaseInfoFun)
                g_updateMarkupBaseInfoFun(baseI);

        // layer read start

        var layerInfoElement = xmlDoc.getElementsByTagName("LayerInfo");

        if (layerInfoElement.length != 0) {
                var layers = layerInfoElement[0].getElementsByTagName("Layer");
                console.log("layers = " + layers.length);
                g_layerList = [];
                for (var i = 0; i < layers.length; i++) {
                        var layerInfo = {};
                        var tempInfo = layers[i];
                        layerInfo.id = i;
                        layerInfo.sName = tempInfo.getAttribute("sName");
                        layerInfo.nColor = genValidColorStr(tempInfo.getAttribute("nColor"));
                        layerInfo.nFillType = tempInfo.getAttribute("nFillType");
                        layerInfo.nFillColor = genValidColorStr(tempInfo.getAttribute("nFillColor"));
                        layerInfo.nPenStyle = tempInfo.getAttribute("nPenStyle");
                        layerInfo.nState = tempInfo.getAttribute("nState");
                        g_layerList.push(layerInfo);
                }

                var nActiveIndex = getValueAndFliterDot(layerInfoElement[0], "nActiveIndex");
                g_layerActiveId = g_layerList[Number(nActiveIndex)].id;
        } else {
                g_layerList = [];
                var layerInfo_default = {};

                layerInfo_default.id = 0;
                layerInfo_default.sName = "no_name_00";
                layerInfo_default.nColor = "#FF0000";
                layerInfo_default.nFillType = "0";
                layerInfo_default.nFillColor = "#FF0000";
                layerInfo_default.nPenStyle = "0";
                layerInfo_default.nState = "1";
                g_layerList.push(layerInfo_default);

                g_layerActiveId = 0;
        }

        // layer read end

        //提取数据
        var countrys = xmlDoc.getElementsByTagName("Entity");

        for (i = 0; i < countrys.length; i++) {
                var markupData = transMarkupDataFromFile(countrys[i]);
                var testRect = genMarkupDrawingByData(markupData);

                if (testRect && testRect.doAtAddEnd != null) {
                        testRect.doAtAddEnd();
                        testRect.addContents();
                        testRect.addBoundBoxContents();
                }
                g_markupList.push(testRect);
        }
        return true;
}

function transMarkupDataFromFile(e) {
        var markupData = {};
        var pointList = [];
        var points = e.getElementsByTagName("Point");

        for (var i = 0; i < points.length; i++) {
                var tempPoint = points[i];
                pointList.push({
                        x: Number(tempPoint.getAttribute("x")) - Number(g_positionDeviation.x),
                        y: Number(tempPoint.getAttribute("y")) - Number(g_positionDeviation.y),
                });
        }
        markupData.pointList = pointList;

        var nRGBLColor_temp = getValueAndFliterDot(e, "nRGBLColor");
        var nRGBLColor_temp_temp = genValidColorStr(nRGBLColor_temp);
        markupData.selectedLineColor = nRGBLColor_temp_temp;

        var nRGBFillColor_temp = getValueAndFliterDot(e, "nRGBFillColor");
        var nRGBFillColor_temp_temp = genValidColorStr(nRGBFillColor_temp);
        markupData.selectedFillColor = nRGBFillColor_temp_temp;

        markupData.selectedFillType = Number(getValueAndFliterDot(e, "sFillType"));
        markupData.selectedLineWidth = Number(getValueAndFliterDot(e, "wLineThick")) + 1;
        markupData.selectedLineType = Number(getValueAndFliterDot(e, "sLineStyle"));

        markupData.selectedFontSize = Number(getValueAndFliterDot(e, "sFontHeight"));
        markupData.text = getValueAndFliterDot(e, "strTextContents");
        markupData.fEntType = getValueAndFliterDot(e, "fEntType");

        markupData.fontWidth = Number(getValueAndFliterDot(e, "sFontWidth")) * 2;

        let originFontStr = getValueAndFliterDot(e, "strFontName");
        markupData.selectedFont = checkFontIndexFromDefaultFontList(originFontStr);

        let tempLayerIndex = getValueAndFliterDot(e, "sLayIndex");
        markupData.sLayIndex = tempLayerIndex.length > 0 ? tempLayerIndex : 0;
        return markupData;
}

function genMarkupDrawingByData(markupData) {
        var testRect = null;
        if (markupData.fEntType == 1)
                testRect = new MarkupLine(markupData, markupData.fEntType);
        else if (markupData.fEntType == 2)
                testRect = new MarkupLine(markupData, markupData.fEntType);
        else if (markupData.fEntType == 3)
                testRect = new MarkupLine(markupData, markupData.fEntType);
        else if (markupData.fEntType == 4 || markupData.fEntType == 5 || markupData.fEntType == 12) {
                var point0 = markupData.pointList[0];
                var point1 = markupData.pointList[1];
                var maxx = Math.max(point0.x, point1.x);
                var minx = Math.min(point0.x, point1.x);
                var maxy = Math.max(point0.y, point1.y);
                var miny = Math.min(point0.y, point1.y);
                markupData.pointList[0].x = minx;
                markupData.pointList[0].y = miny;
                markupData.pointList[1].x = maxx;
                markupData.pointList[1].y = maxy;

                testRect = new MarkupRect(markupData, markupData.fEntType);
        } else if (markupData.fEntType == 6) {
                var point0 = markupData.pointList[0];
                var point1 = markupData.pointList[1];
                var maxx = Math.max(point0.x, point1.x);
                var minx = Math.min(point0.x, point1.x);
                var maxy = Math.max(point0.y, point1.y);
                var miny = Math.min(point0.y, point1.y);
                markupData.pointList[0].x = minx;
                markupData.pointList[0].y = miny;
                markupData.pointList[1].x = maxx;
                markupData.pointList[1].y = maxy;

                testRect = new MarkupEllipse(markupData, markupData.fEntType);
        } else if (markupData.fEntType == 7)
                testRect = new MarkupArc(markupData, markupData.fEntType);
        else if (markupData.fEntType == 8)
                testRect = new MarkupHandDraw(markupData, markupData.fEntType);
        else if (markupData.fEntType == 9)
                testRect = new MarkupCloudDraw(markupData, markupData.fEntType);
        else if (markupData.fEntType == 10) {
                var point0 = markupData.pointList[0];
                var point1 = markupData.pointList[1];
                var maxx = Math.max(point0.x, point1.x);
                var minx = Math.min(point0.x, point1.x);
                var maxy = Math.max(point0.y, point1.y);
                var miny = Math.min(point0.y, point1.y);
                markupData.pointList[0].x = minx;
                markupData.pointList[0].y = miny;
                markupData.pointList[1].x = maxx;
                markupData.pointList[1].y = maxy;
                testRect = new MarkupText(markupData, markupData.fEntType);
        } else if (markupData.fEntType == 11) { // text
                testRect = new MarkupPolylineAndText(markupData, markupData.fEntType);
        } else if (markupData.fEntType >= 13 && markupData.fEntType <= 16) { // text
                testRect = new MarkupBallMarker(markupData, markupData.fEntType);
        }

        if (testRect && testRect.doAtAddEnd != null) {
                testRect.doAtAddEnd();
                testRect.addContents();
                testRect.addBoundBoxContents();
        }
        return testRect;
}


function genMarkupsContent(baseInfo) {
        var createXMLDOM = function () {
                var xmlDOM;
                if (window.ActiveXObject) {
                        xmlDOM = new ActiveXObject('Microsoft.XMLDOM');
                } else if (document.implementation &&
                        document.implementation.createDocument) {
                        xmlDOM = document.implementation.createDocument('', '', null);
                } else {
                        alert('您的浏览器不支持文档対象XMLDOM');
                        return;
                }
                return xmlDOM;
        }

        var parserXMLToString = function (xmlDOM) {
                if (window.ActiveXObject) {
                        return xmlDOM.xml;
                } else if (document.implementation &&
                        document.implementation.createDocument) {
                        return new XMLSerializer().serializeToString(xmlDOM);
                }
        }

        var genColorStr = function (inColor) {
                var replaceed = inColor.replace("#", "");
                var rStr = replaceed.substring(0, 2);
                var gStr = replaceed.substring(2, 4);
                var bStr = replaceed.substring(4, 6);

                var out = "0x00" + bStr + gStr + rStr;
                return out;
        }

        var genLayIndex = function (layId) {
                for (var i = 0; i < g_layerList.length; i++) {
                        if (layId == g_layerList[i].id)
                                return i;
                }
                return -1;
        }

        var xmlDOM = createXMLDOM();
        if (xmlDOM == null) {
                return null;
        }

        var jpcMarkup = xmlDOM.createElement('jpcMarkup');
        xmlDOM.appendChild(jpcMarkup);

        var _baseInfo = xmlDOM.createElement('BaseInfo');
        jpcMarkup.appendChild(_baseInfo);

        var lstField = xmlDOM.createElement('lstField');
        _baseInfo.appendChild(lstField);

        if (baseInfo) {
                var userName = xmlDOM.createElement('UserName');
                lstField.appendChild(userName);
                userName.appendChild(xmlDOM.createTextNode(baseInfo.userName));

                var departName = xmlDOM.createElement('DepartName');
                lstField.appendChild(departName);
                departName.appendChild(xmlDOM.createTextNode(baseInfo.departName));

                var companyName = xmlDOM.createElement('CompanyName');
                lstField.appendChild(companyName);
                companyName.appendChild(xmlDOM.createTextNode(baseInfo.companyName));

                var address = xmlDOM.createElement('Address');
                lstField.appendChild(address);
                address.appendChild(xmlDOM.createTextNode(baseInfo.address));

                var phoneNumber = xmlDOM.createElement('PhoneNumber');
                lstField.appendChild(phoneNumber);
                phoneNumber.appendChild(xmlDOM.createTextNode(baseInfo.phoneNumber));
        }

        // gen layer info
        var _layerInfo = xmlDOM.createElement('LayerInfo');
        jpcMarkup.appendChild(_layerInfo);
        var _nActiveIndex = xmlDOM.createElement('nActiveIndex');

        if (g_layerList.length != 0 && g_layerActiveId != -1) {
                for (var i = 0; i < g_layerList.length; i++) {
                        if (g_layerActiveId == g_layerList[i].id) {
                                _nActiveIndex.appendChild(xmlDOM.createTextNode(i));
                                _layerInfo.appendChild(_nActiveIndex);
                                break;
                        }
                }

                for (var j = 0; j < g_layerList.length; j++) {
                        let tempLayer = g_layerList[j];
                        var _tempLayerElement = xmlDOM.createElement('Layer');
                        _tempLayerElement.setAttribute("sName", tempLayer.sName);
                        _tempLayerElement.setAttribute("nColor", genColorStr(tempLayer.nColor));
                        _tempLayerElement.setAttribute("nFillType", tempLayer.nFillType);
                        _tempLayerElement.setAttribute("nFillColor", genColorStr(tempLayer.nFillColor));
                        _tempLayerElement.setAttribute("nPenStyle", tempLayer.nPenStyle);
                        _tempLayerElement.setAttribute("nState", tempLayer.nState);
                        _tempLayerElement.appendChild(xmlDOM.createTextNode(""));
                        _layerInfo.append(_tempLayerElement);
                }
        } else {
                _nActiveIndex.appendChild(xmlDOM.createTextNode("0"));
                _layerInfo.appendChild(_nActiveIndex);
                var __tempLayerElement = xmlDOM.createElement('Layer');

                __tempLayerElement.setAttribute("sName", "no_name_00");
                __tempLayerElement.setAttribute("nColor", genColorStr("#FF0000"));
                __tempLayerElement.setAttribute("nFillType", "0");
                __tempLayerElement.setAttribute("nFillColor", genColorStr("#FF0000"));
                __tempLayerElement.setAttribute("nPenStyle", "0");
                __tempLayerElement.setAttribute("nState", "1");
                _layerInfo.append(__tempLayerElement);
        }

        // gen layer info end 

        var entityData = xmlDOM.createElement('EntityData');
        jpcMarkup.appendChild(entityData);

        for (var i = 0; i < g_markupList.length; i++) {
                var tempMarkupListItem = g_markupList[i];
                var newEntity = xmlDOM.createElement('Entity');
                entityData.appendChild(newEntity);

                // <nID>"19"</nID>
                var entityNID = xmlDOM.createElement('nID');
                entityNID.appendChild(xmlDOM.createTextNode(tempMarkupListItem.id));
                newEntity.appendChild(entityNID);

                var entityLayIndex = xmlDOM.createElement('sLayIndex');
                entityLayIndex.appendChild(xmlDOM.createTextNode(genLayIndex(tempMarkupListItem.sLayId)));
                newEntity.appendChild(entityLayIndex);

                //<fEntType>"1"</fEntType>
                var entityfEntType = xmlDOM.createElement('fEntType');
                entityfEntType.appendChild(xmlDOM.createTextNode(tempMarkupListItem.typeId));
                newEntity.appendChild(entityfEntType);

                // <sLineStyle>"1"</sLineStyle>
                var entitysLineStyle = xmlDOM.createElement('sLineStyle');
                entitysLineStyle.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedLineType));
                newEntity.appendChild(entitysLineStyle);

                // <wLineThick>"8"</wLineThick>
                var entitywLineThick = xmlDOM.createElement('wLineThick');
                entitywLineThick.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedLineWidth - 1));
                newEntity.appendChild(entitywLineThick);

                // <sFillType>"1"</sFillType>
                var entitysFillType = xmlDOM.createElement('sFillType');
                entitysFillType.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedFillType));
                newEntity.appendChild(entitysFillType);

                // <nRGBLColor>"0x000000FF"</nRGBLColor>
                var entitynRGBLColor = xmlDOM.createElement('nRGBLColor');
                entitynRGBLColor.appendChild(xmlDOM.createTextNode(genColorStr(tempMarkupListItem.originData.selectedLineColor)));
                newEntity.appendChild(entitynRGBLColor);

                // <nRGBFillColor>"0x00FFFF00"</nRGBFillColor>
                var entitynRGBFillColor = xmlDOM.createElement('nRGBFillColor');
                entitynRGBFillColor.appendChild(xmlDOM.createTextNode(genColorStr(tempMarkupListItem.originData.selectedFillColor)));
                newEntity.appendChild(entitynRGBFillColor);

                for (var j = 0; j < tempMarkupListItem.originData.pointList.length; j++) {
                        var temppoint = tempMarkupListItem.originData.pointList[j];
                        var point = xmlDOM.createElement('Point');
                        point.setAttribute('x', temppoint.x.toFixed(6));
                        point.setAttribute('y', temppoint.y.toFixed(6));
                        point.setAttribute('z', "0.000000");
                        point.appendChild(xmlDOM.createTextNode(" "));
                        newEntity.appendChild(point);
                }

                // <sFontHeight>"10"</sFontHeight>
                var entitysFontHeight = xmlDOM.createElement('sFontHeight');
                entitysFontHeight.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedFontSize));
                newEntity.appendChild(entitysFontHeight);

                // <sFontWidth>"5"</sFontWidth>
                var entitysFontWidth = xmlDOM.createElement('sFontWidth');
                entitysFontWidth.appendChild(xmlDOM.createTextNode(Math.round(tempMarkupListItem.originData.fontWidth / 2)));
                newEntity.appendChild(entitysFontWidth);

                // <sFontBold>"0"</sFontBold>
                var entitysFontBold = xmlDOM.createElement('sFontBold');
                entitysFontBold.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedBold ? "400" : "0"));
                newEntity.appendChild(entitysFontBold);

                // <bFontItaly>"0"</bFontItaly>
                var entitybFontItaly = xmlDOM.createElement('bFontItaly');
                entitybFontItaly.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedItalics ? "1" : "0"));
                newEntity.appendChild(entitybFontItaly);

                // <bFontUnderLine>"0"</bFontUnderLine>
                var entitybFontUnderLine = xmlDOM.createElement('bFontUnderLine');
                entitybFontUnderLine.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.selectedUnderline ? "1" : "0"));
                newEntity.appendChild(entitybFontUnderLine);

                // <strFontName>"楷体"</strFontName>
                var entitystrFontName = xmlDOM.createElement('strFontName');
                let fontNameStr = checkFontNameFromDefaultFontList(tempMarkupListItem.originData.selectedFont);
                entitystrFontName.appendChild(xmlDOM.createTextNode(fontNameStr));
                newEntity.appendChild(entitystrFontName);

                var entitystrTextContents = xmlDOM.createElement('strTextContents');
                entitystrTextContents.appendChild(xmlDOM.createTextNode(tempMarkupListItem.originData.text));
                newEntity.appendChild(entitystrTextContents);
        }

        var xmlStr = "<?xml version=\"1.0\" encoding=\"Shift-JIS\"?>" + parserXMLToString(xmlDOM);
        // console.log(xmlStr);

        var re = formateXml(xmlStr)
        console.log(re);
        return re;
}

//格式化xml代码
function formateXml(xmlStr) {
        var text = xmlStr;
        //使用replace去空格
        text = '\n' + text.replace(/(<\w+)(\s.*?>)/g, function ($0, name, props) {
                return name + ' ' + props.replace(/\s+(\w+=)/g, " $1");
        }).replace(/>\s*?</g, ">\n<");
        //处理注释
        text = text.replace(/\n/g, '\r').replace(/<!--(.+?)-->/g, function ($0, text) {
                var ret = '<!--' + escape(text) + '-->';
                return ret;
        }).replace(/\r/g, '\n');
        //调整格式  以压栈方式递归调整缩进
        var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
        var nodeStack = [];
        var output = text.replace(rgx, function ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) {
                var isClosed = (isCloseFull1 == '/') || (isCloseFull2 == '/') || (isFull1 == '/') || (isFull2 == '/');
                var prefix = '';
                if (isBegin == '!') { //!开头
                        prefix = setPrefix(nodeStack.length);
                } else {
                        if (isBegin != '/') { ///开头
                                prefix = setPrefix(nodeStack.length);
                                if (!isClosed) { //非关闭标签
                                        nodeStack.push(name);
                                }
                        } else {
                                nodeStack.pop(); //弹栈
                                prefix = setPrefix(nodeStack.length);
                        }
                }
                var ret = '\n' + prefix + all;
                return ret;
        });
        var outputText = output.substring(1);
        //还原注释内容
        outputText = outputText.replace(/\n/g, '\r').replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
                if (prefix.charAt(0) == '\r')
                        prefix = prefix.substring(1);
                text = unescape(text).replace(/\r/g, '\n');
                var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/mg, prefix) + '-->';
                return ret;
        });
        outputText = outputText.replace(/\s+$/g, '').replace(/\r/g, '\r\n');
        return outputText;
}

//计算头函数 用来缩进
function setPrefix(prefixIndex) {
        var result = '';
        var span = '    '; //缩进长度
        var output = [];
        for (var i = 0; i < prefixIndex; ++i) {
                output.push(span);
        }
        result = output.join('');
        return result;
}

function showAllMarkups(e) {
        // if(g_SelectedMarkup != null) {
        //   g_SelectedMarkup.setSelected(false);
        //   g_SelectedMarkup = null;
        // }
        clearSelectedState();


        if (_self.markup_groups)
                _self.markup_groups.attr("visibility", e ? "visible" : "hidden");

        if (_self.markup_groups_bottom)
                _self.markup_groups_bottom.attr("visibility", e ? "visible" : "hidden");
}

// --------------  layer ------------- //

function getLayersData() {
        return g_layerList;
}

function getActiveLayerIndex() {
        return g_layerActiveId;
}

function setLayersData(e) {
        g_layerList = e;
}

function setActiveLayerIndex(e) {
        clearSelectedState();
        g_layerActiveId = e;
        clearSelectedState();

}

function updateMarkupsVisiableByData() {
        for (var i = 0; i < g_markupList.length; i++) {
                let markupitem = g_markupList[i];
                if (markupitem.sLayId == null)
                        continue;

                let isMarkShouldDelete = true;
                for (var j = 0; j < g_layerList.length; j++) {
                        let layeritem = g_layerList[j];
                        if (markupitem.sLayId == layeritem.id) {
                                isMarkShouldDelete = false;
                                if (layeritem.nState == 1) {
                                        markupitem.rootGroup.attr("visibility", null);
                                        markupitem.contentGroupBottom.attr("visibility", null);
                                } else {
                                        markupitem.rootGroup.attr("visibility", "hidden");
                                        markupitem.contentGroupBottom.attr("visibility", "hidden");
                                }
                        }
                }

                if (isMarkShouldDelete) {
                        tryDeleteMarkupByData(g_markupList[i])
                        i--;
                }
        }
}

function getDefaultLayerData() {
        for (var j = 0; j < g_layerList.length; j++) {
                let layeritem = g_layerList[j];
                if (layeritem.id == g_layerActiveId) {
                        return layeritem;
                }
        }
        return null;
}
// --------------  layer ------------- //


/**
 * 
 * @param {*} inData 球标数据list
 */
function genMarkupOrignDataFromExternalData(inData) {
        for (var j = 0; j < inData.length; j++) {
                var tempOrignDataItem = inData[j];
                var markupData = {};
                // gen points
                var pointList = [];
                var points = tempOrignDataItem.points;
                for (var i = 0; i < points.length; i++) {
                        var tempPoint = points[i];
                        pointList.push({
                                x: Number(tempPoint.x) - Number(g_positionDeviation.x),
                                y: Number(tempPoint.y) - Number(g_positionDeviation.y),
                        });
                }
                markupData.pointList = pointList;

                // line color
                markupData.selectedLineColor = tempOrignDataItem.lineColor;

                // fill color
                markupData.selectedFillColor = tempOrignDataItem.ballFillColor;

                // filltype
                markupData.selectedFillType = "0";

                // wLineThick
                markupData.selectedLineWidth = tempOrignDataItem.lineWidth;

                // sLineStyle
                markupData.selectedLineType = tempOrignDataItem.lineStyle;

                // sFontHeight
                markupData.selectedFontSize = tempOrignDataItem.fontSize;

                // strTextContents
                markupData.text = tempOrignDataItem.showID;

                // bln_kbn
                markupData.bln_kbn = tempOrignDataItem.bln_kbn;

                // bln_dtlno
                markupData.bln_dtlno = tempOrignDataItem.bln_dtlno;

                // fEntType
                markupData.fEntType = tempOrignDataItem.shapeType;

                // sFontWidth
                markupData.fontWidth = Number(tempOrignDataItem.fontSize) / 2;

                // strFontName
                markupData.originFontStr = tempOrignDataItem.fontName;
                markupData.selectedFont = checkFontIndexFromDefaultFontList(markupData.originFontStr);

                markupData.selectedFillType = 1;
                // markup id
                markupData.posOrder = tempOrignDataItem.sId;
                var testRect = genMarkupDrawingByData(markupData);
                g_markupList.push(testRect);
        }
}

function changeSelectStatusById(val, justUi = true, isClear = true) {
        console.log(val, g_markupList)
        if (isClear) {
                clearSelectedState();
        }

        for (var i = 0; i < g_markupList.length; i++) {
                let tempMarkup = g_markupList[i];
                if (tempMarkup.originData.prlNo == val) {
                        tempMarkup.setSelected(true)
                }
        }
}

function isSelectedMarkup() {
        return g_SelectedMarkup == null ? false : true;
}

function getAllMarks() {
        return g_markupList;
}

/**
 * 替换图纸中元素的属性
 * @param {*} e tagName：节点名 paramName：属性名 newValue：更新值
 */
async function changeSvgElementData(e) {
        // 首先检査是否已经存在 loadingNode 并移除它  
        d3.selectAll('#gright-CAD .loading-text').remove();
        let loadingNode = d3.select('#gright-CAD')
                .append("text")
                .attr("class", "loading-text") // 添加一个唯一的类名  
                .attr("x", '27%')
                .attr("y", '40%')
                .attr("width", '100%')
                .attr("height", '100%')
                .attr("transform", 'scale(1,-1)')
                .attr("fill", "#333") // 设置文本颜色为浅灰色
                .text('Loading...')

        var tempPath = e.newValue;
        if (e.tagName == "img-content") {

                tempPath = await getBlobPath({
                        path: e.newValue,
                        isTIFF: e.newValue.indexOf('.tif') != -1 || e.newValue.indexOf('.tiff') != -1 ? true : false
                })
        }
        console.log('tempPath', tempPath);

        // 図面サイズを取得し、markup_groupの倍率を調整
        if (g_boxWidth != undefined && g_boxHeight != undefined) {
                getImageSize(tempPath).then(size => {
                        console.log(`Width: ${size.width}, Height: ${size.height}`);
                        // BMP以外は拡大と縮小のどちらも実施、BMPは縮小のみ
                        if ((e.newValue.indexOf('.bmp') == -1) || (size.width > g_boxWidth || size.height > g_boxHeight)) {
                                let boxSizeScaleWidth = g_boxWidth / size.width;
                                let boxSizeScaleHeight = g_boxHeight / size.height;
        
                                if (boxSizeScaleWidth < boxSizeScaleHeight) {
                                        g_markupsScale = boxSizeScaleWidth
                                        let viewImgHeight = size.height * boxSizeScaleWidth;
                                        g_markupsOffsetHeight = (g_boxHeight - viewImgHeight) / 2;
                                        g_markupsOffsetWidth = 0;
                        
                                        // markup_group
                                        // _self.markup_groups.attr("transform", `translate(0, ${-imgSpaceHeight}) scale(${boxSizeScaleWidth}, -${boxSizeScaleWidth})`);
                                        _self.markup_groups.attr("transform", `translate(0, ${-g_markupsOffsetHeight}) scale(${g_markupsScale})`);

                                        _self.markup_groups_bottom.attr("transform", `translate(0, ${-g_markupsOffsetHeight}) scale(${g_markupsScale})`);
                                } else {
                                        g_markupsScale = boxSizeScaleHeight
                                        let viewImgWidth = size.width * boxSizeScaleHeight;
                                        g_markupsOffsetWidth = (g_boxWidth - viewImgWidth) / 2;
                                        g_markupsOffsetHeight = 0;
        
                                        // markup_group
                                        // _self.markup_groups.attr("transform", `translate(${imgSpaceWidth}, 0) scale(${boxSizeScaleHeight}, -${boxSizeScaleHeight})`);
                                        _self.markup_groups.attr("transform", `translate(${g_markupsOffsetWidth}, 0) scale(${g_markupsScale})`);

                                        _self.markup_groups_bottom.attr("transform", `translate(${g_markupsOffsetWidth}, 0) scale(${g_markupsScale})`);
                                }
                        }
                }).catch(error => {
                        console.log('Error loading image:', error);
                });
        }

        d3.selectAll('#gright-CAD .loading-text').remove();
        d3.select("#" + e.tagName).attr(e.paramName, tempPath);
}

function getSelectMarkupData() {
        if (g_SelectedMarkup)
                return g_SelectedMarkup.originData;
        return null;
}

function exportSvgDataStr(divId) {
        if (_self.svg)
                return _self.svg.node().outerHTML;
        else
                return "";
        // var tar = document.getElementById(divId);
        // return tar.outerHTML;
}

export {
        AddSvg as AddSvg,
        removeSvg as removeSvg,

        setIsMarkupStatus as setIsMarkupStatus,
        setSvgLineWidthRatio as setSvgLineWidthRatio,
        setSvgBoundingBoxRatio as setSvgBoundingBoxRatio,
        setCanClickSelectMarkup as setCanClickSelectMarkup,
        setCanEditSelectMarkup as setCanEditSelectMarkup,
        setEditDotWidthRatio as setEditDotWidthRatio,
        ResetSvgView as ResetSvgView,
        SetSvgMouseMode as SetSvgMouseMode,
        GetMousePositonOnSvgX as GetMousePositonOnSvgX,
        GetMousePositonOnSvgY as GetMousePositonOnSvgY,
        initMarkupLayer as initMarkupLayer,
        setGParams as setGParams,

        getSelectMarkupData as getSelectMarkupData,

        changeGlobalState as changeGlobalState,
        setSelectCallBack as setSelectCallBack,
        setLoadCallBack as setLoadCallBack,
        setOpenInputTextCallBack as setOpenInputTextCallBack,
        onInputDialogClose as onInputDialogClose,
        loadMarkupsFromFile as loadMarkupsFromFile,
        setUpdateMarkupBaseInfoCallback as setUpdateMarkupBaseInfoCallback,
        setContextMenuDoubleClickFun as setContextMenuDoubleClickFun,
        setLeftMouseClickFun as setLeftMouseClickFun,
        tryDeleteSelectMarkup as tryDeleteSelectMarkup,
        Del_g_SelectedMarkup as Del_g_SelectedMarkup,
        genMarkupsContent as genMarkupsContent,
        clearAllMarkups as clearAllMarkups,
        showAllMarkups as showAllMarkups,

        getLayersData as getLayersData,
        getActiveLayerIndex as getActiveLayerIndex,
        setLayersData as setLayersData,
        setActiveLayerIndex as setActiveLayerIndex,
        updateMarkupsVisiableByData as updateMarkupsVisiableByData,
        getDefaultLayerData as getDefaultLayerData,
        clearSelectedState as clearSelectedState,
        genMarkupOrignDataFromExternalData as genMarkupOrignDataFromExternalData,
        changeSelectStatusById as changeSelectStatusById,
        changeSvgElementData as changeSvgElementData,
        setCanFitPositionAndScale as setCanFitPositionAndScale,
        setOnAddMarkupDataFun as setOnAddMarkupDataFun,

        testAddLineGroupsByParams as testAddLineGroupsByParams,

        exportSvgDataStr,

        MarkupRect as MarkupRect,
        MarkupLine as MarkupLine,
        MarkupEllipse as MarkupEllipse,
        MarkupArc as MarkupArc,
        MarkupText as MarkupText,
        MarkupHandDraw as MarkupHandDraw,
        MarkupCloudDraw as MarkupCloudDraw,
        isSelectedMarkup,
        getAllMarks
}